Was ist das :: content / :: slotted Pseudoelement und wie funktioniert es?

74

Für Google ist dies unmöglich, da in jedem Artikel, der über die :beforeund :afterPseudoelemente spricht , das Wort "Inhalt" verwendet wird.

Ich habe in diesem CSS-Tricks-Artikel davon gehört und erklärt, wie ein Bildschieberegler als Anwendungsbeispiel für Webkomponenten implementiert wird. Das darin enthaltene Codebeispiel lautet wie folgt:

CSS

#slides ::content img {
   width: 25%;
   float: left;
}

HTML

<template>
  ...
  <div class="inner">
    <content select="img"></content>
  </div>
</template>

Es scheint sich auf dieses <content>Tag zu beziehen , mit dem der Benutzer Webkomponenten einbinden kann, aber ich würde dies gerne genauer verstehen.

BEARBEITEN:

Nachdem ich weiter gelesen hatte, entdeckte ich in dem oben genannten Artikel einen Link zum "Shadow DOM CSS Cheatsheet" des Autors, der eine Passage enthält, die erklärt, was das Pseudoelement ::contentist:

Wählt verteilte Knoten innerhalb eines Elements aus. Muss für Browser, die den nativen Selektor nicht unterstützen, mit Polyfill-Next-Selector gekoppelt werden.

::content h1 {
    color: red;
}

Quelle: http://robdodson.me/blog/2014/04/10/shadow-dom-css-cheat-sheet/

Das ist hilfreich, aber ich finde die ganze Angelegenheit immer noch ziemlich undurchsichtig. Irgendwelche zusätzlichen Erkenntnisse?

jon
quelle
5
Die Spezifikation bietet möglicherweise zusätzliche Einblicke.
Paulie_D
1
@Paulie_D hat gerade das Cheatsheet gesehen (einen Link in Frage oben hinzugefügt) - danke! aber immer noch das ganze Konzept als unklar zu finden. Was sind verteilte Knoten?
Jon
4
Weitere
Informationen
2
::contentwurde umbenannt in::slotted
Oriol
Danke Oriol. @jon Ich habe meine Antwort aktualisiert, um dies widerzuspiegeln. Sobald Browser die Unterstützung auf slotund verlagern slotted, werde ich die Erwähnungen von contentund ersetzen ::contentund wahrscheinlich auch die Frage aktualisieren, damit sie für zukünftige Leser nützlich bleibt!
TylerH

Antworten:

109

Das ::contentPseudoelement wird in zukünftigen Implementierungen von Web Components / Shadow DOM durch das ::slottedPseudoelement ersetzt. Ebenso hat das Element dieses Pseudoelement gezielt geändert von <contentbis <slot> in der neuesten Version der Schatten DOM - Spezifikation . Eine entsprechende Diskussion zu dieser Änderung finden Sie hier .

Derzeit unterstützen Browser noch <content>und ::content.


Ursprüngliche Antwort:


Zusammenfassung:

::contentist im Wesentlichen eine Möglichkeit, tiefer zu graben und Nachkommen von zu ShadowHoststylen, die normalerweise nicht zum Stylen verfügbar sind, da Ihr CSS nicht weiß, ohne das ShadowDOM-Fragment zu suchen ::content.


Diese Antwort wird vorausgesetzt , Sie sind zumindest etwas vertraut mit dem <template>Element und Web Components , insbesondere die ShadowDOM , die sich mit ShadowTrees und ihre zwei Hauptelemente, ShadowHostund ShadowRoot.

Hinweis - Zum jetzigen Zeitpunkt werden Webkomponenten in allen fünf Hauptbrowsern zu weniger als 50% unterstützt (sogar standardmäßig vorangestellt, standardmäßig unterstützt). Während alle modernen Browser unterstützen <template>, unterstützen nur neuere Versionen von Chrome und Opera das ShadowDOM vollständig. mit Firefox, das Teile davon unterstützt, nachdem Sie die erforderliche Funktion in about:config( dom.webcomponents.enabled) auf true umgeschaltet haben .

Das Ziel der Verwendung von ShadowDOMähnelt der Trennung von Bedenken durch MVC . Das heißt, wir möchten unseren Inhalt von unserer Präsentation trennen und gekapselte Vorlagen in unserem Code zulassen, um die Verwaltung zu vereinfachen. Wir haben dies bereits in verschiedenen Programmiersprachen, aber es ist seit einiger Zeit ein Problem in HTML und CSS. Darüber hinaus kann es beim Stylen von Elementen in Webanwendungen zu Konflikten mit Klassennamen kommen.

Normalerweise interagieren wir mit dem LightDOM(einer Art "Lichtreich"), aber manchmal wäre es hilfreich, die Kapselung zu nutzen. Das Überqueren dieser Art von "Schattenbereich" (Teil von Webkomponenten) ist eine neue Methode, um die oben genannten Probleme zu verhindern, indem die Kapselung zugelassen wird . Alle Stile, die auf Markups in Ihrem angewendet ShadowTreewerden, gelten nicht für Markups außerhalb von Ihnen ShadowTree, selbst wenn genau dieselben Klassen oder Selektoren verwendet werden.

Wenn der ShadowTree(der im lebt ShadowDOM) einen Baum aus dem darin LightDOMverteilten hat und / oder wenn der ShadowTreegerendert wird, wird das Ergebnis vom Browser in einen sogenannten zusammengesetzten Baum konvertiert .

Wenn der Browser den Code macht, die Inhalte an neuen Standorten verteilt und eingesetzt wird außer wo es physisch eingegeben wurde. Diese verteilte Ausgabe ist das, was Sie sehen (und was der Browser sieht) und wird als bezeichnet composed tree. In Wirklichkeit wird der Inhalt ursprünglich nicht in der Reihenfolge eingegeben, in der er jetzt angezeigt wird, aber Sie werden dies nicht wissen, und der Browser auch nicht. Diese Trennung zwischen "Endergebnis" und "Originalcode" ist, wenn Sie so wollen, einer der Hauptvorteile der Kapselung.

Web Components & the Future of CSS ist ein großartiges 40-minütiges Video über Web Components und speziell das ShadowDOM, auf das ZachSaucier mich hingewiesen hat .


Speziell für Ihre Frage gilt das ::contentPseudoelement für sogenannte verteilte Knoten . Ein verteilter Knoten ist ein anderer Begriff für alles, was Sie in die <content></content>Tags einfügen. Der Inhalt wird verteilt von seinem Platz in der ursprünglichen Markup , wo Sie Ihre platziert haben <content>Tags in der Vorlage.

Wenn Sie also Spezifität in CSS benötigen, können Sie mit Selektoren normalerweise umgehen, indem Sie zum übergeordneten Element gehen und dieses als Teil des Selektors hinzufügen. Beispiel: Wenn dies .container {}nicht spezifisch genug ist, können Sie div .container {}oder .main .container {}verwenden, damit Ihr Selektor funktioniert.

Wenn Sie über den Punkt des ShadowDOM nachdenken, der sich auf Umfang und Kapselung bezieht, müssen Sie erkennen, dass dieser neue ShadowTree, den Sie erstellt haben, ein völlig neues (diskretes) DOM-Fragment ist. Es befindet sich nicht im selben "Lichtbereich" wie der Rest Ihres Inhalts. Es ist in einem "Schattenreich". Woher weiß das CSS, dass es auf dieses "Schattenreich" abzielt? Mit dem ::contentPseudoelement!

Der ::contentPseudoelement-Selektor fungiert als übergeordnetes Element verteilter Knoten.

HTML5Rocks bietet hier , hier und hier eine große Auswahl an Tutorials , die weitere Informationen und einige gute Beispiele enthalten (besuchen Sie Chrome oder Opera, bis mehr Browser diese Funktionen unterstützen).

Sehen Sie sich beispielsweise diese modifizierte und verbesserte (von Leo ) Version des Codes von HTML5Rocks an:

var div = document.querySelector('div');
var root = div.createShadowRoot();
var template = document.querySelector('template');

root.appendChild(template.content);
<template>
  <style>
    h3 { color: red; }
    content[select="h3"]::content > h3 { color: green; }
    ::content section p { text-decoration: underline; }
  </style>
  <h3>Shadow DOM</h3>
  <content select="h3"></content>
  <content select="section"></content>
</template>

<div>
  <h3>Light DOM</h3>
  <section>
    <div>I'm not underlined</div>
    <p>I'm underlined in Shadow DOM!</p>
  </section>
</div>

Auch auf JSFiddle verfügbar (Denken Sie daran, einen WebKit-basierten Browser wie Chrome oder Opera zu besuchen.)

Hier können Sie sehen , dass das Pseudoelement zuerst den Inhalt der Auswahl , die den Inhalt des ist Element in Ihrem Markup, und dann weiter spezifiziert durch Zugabe .::contentsection pShadowRootdivsection p

Dies mag im Vergleich zur normalen Verwendung von CSS-Selektoren unnötig erscheinen (z. B. warum nicht einfach verwenden section p {}?), Bis Sie sich daran erinnern, dass Sie beim Durchlaufen von a ShadowTreenormalerweise keine Nachkommen von hostElementen auswählen können (welche verteilten Knoten sind), da sie sich in der befinden "Shadow Realm" habe ich bereits erwähnt.

TylerH
quelle
11
Dies ist eine phänomenale Antwort. Vielen Dank, dass Sie sich die Zeit genommen haben, es zu schreiben!
Jon
1
@jon Gern geschehen! Ich bin froh, dass Sie es nützlich fanden. Es gibt auch ein drittes Tutorial von HTML5Rocks, wenn Sie noch nach Informationen suchen.
TylerH
2
Die Newline, die durch einen Backslash entkommen ist, wird nicht empfohlen, da es sich nicht um ECMAScript handelt
Juan Mendes
4
@JuanMendes Nach dem, was ich gerade gelesen habe: "Das \ gefolgt von einer neuen Zeile ist keine Zeichen-Escape-Sequenz, sondern eine LineContinuation. Die neue Zeile wird nicht Teil der Zeichenfolge. Dies ist einfach eine Möglichkeit, a zu verbreiten Zeichenfolge über mehrere Zeilen (zum Beispiel zur einfacheren Bearbeitung von Code) [..] " Quelle . Es ist also anscheinend überhaupt keine Hemmung.
TylerH
1
Nur zu Ihrer Information: Weitere Informationen zu Webkomponenten finden Sie in einer Diashow ("Eine Zukunft namens Webkomponenten"), die auf der Front Trends 2014 von Zeno Rocha (Mitglied des Google Developers Expert Program) vorgestellt wurde - vimeo.com/97308701
Michał Kutra