Das hat mich hier ein wenig verwirrt, also schreibe ich es auf, während es noch frisch im Gedächtnis ist. Nur weil du eine Web Component verwendest, heißt das nicht, dass ihre Stile vollständig isoliert sind. Du könntest Inhalte innerhalb einer Web Component haben, die zusammen mit dem Rest deiner Website normal gestylt werden. Wie hier
Siehe den Pen Web Component mit globalen Stilen (weil kein Shadow DOM) von Chris Coyier (@chriscoyier) auf CodePen.
Dieses Element <whats-up> hat die JavaScript-basierte Funktionalität für sich isoliert, indem es einen Klick-Handler an den <button> darin angehängt hat. Aber das Styling dieses Buttons stammt von globalem CSS, das auf diese Seite angewendet wird.
Das Template in die Web Component verschieben
Aber nehmen wir an, wir verschieben den <button> in die Web Component, damit wir <whats-up> ganz allein verwenden können. Das könnten wir tun, indem wir das benutzerdefinierte Element mit .innerHTML einfügen.
Siehe den Pen Web Component mit globalen Stilen (weil kein Shadow DOM) von Chris Coyier (@chriscoyier) auf CodePen.
Wiederum, vollständig vom globalen CSS gestylt. Cool. Das kann wünschenswert sein. Es kann aber auch unerwünscht sein. Vielleicht hoffst du, dass Web Components Stile für dich isolieren.
Shadow DOMing des Templates
Web Components können Stile isolieren (und die HTML-Implementierung abstrahieren) über den Shadow DOM. Hier ist dieselbe Komponente, die stattdessen Shadow DOM verwendet.
Siehe den Pen Web Component mit lokalen Stilen von Chris Coyier (@chriscoyier) auf CodePen.
Beachte, dass die Funktionalität immer noch funktioniert (obwohl wir durch den shadowRoot querySelector mussten), aber wir haben die globalen Stile *vollständig verloren*. Die Shadow DOM-Grenze (shadow root) verhindert, dass Stile hinein- oder herauskommen (ähnlich wie bei einem iframe).

Es gibt keine globale Methode, diese Grenze zu durchdringen, soweit ich weiß. Wenn du also Stile hineinbringen möchtest, musst du sie in das Template bringen.
Stile (inline) in die Web Component verschieben
Siehe den Pen Web Component mit lokalen Stilen von Chris Coyier (@chriscoyier) auf CodePen.
Das wäre höchst ärgerlich, wenn ihr beide den Shadow DOM wirklich nutzen wolltet, aber auch eure globalen Stile möchtet. Es ist merkwürdig, dass es einen Shadow DOM "Modus" für offen und geschlossen gibt, um JavaScript herein- oder herauszulassen, aber nicht für CSS.
Wenn das auf dich zutrifft, musst du wahrscheinlich deine globalen Stylesheets mit @import importieren, um diese globalen Stile einzubringen, und hoffen, dass sie gecached werden und der Browser so schlau ist, dass es keine großen Leistungseinbußen gibt.
Stattdessen auf externe Stile verlinken
Ich werde die direkte Link-zu-CSS-Funktion von CodePen verwenden, um die Stile aus dem Pen selbst in die Web Component zu importieren.
Siehe den Pen Web Component mit lokalen Stilen von Chris Coyier (@chriscoyier) auf CodePen.
Anscheinend gibt es auf diese Weise keine Möglichkeit, einen gewissen "Flash-Of-Unstyled-Component" zu vermeiden, daher werden Inline-Stile empfohlen, bis es eine gibt. (Nun, schaut euch ::part an).
Benutzerdefinierte Eigenschaften durchdringen den Shadow DOM
Eine weitere wichtige Sache, die man wissen sollte, ist, dass CSS-benutzerdefinierte Eigenschaften den Shadow DOM durchdringen! Das ist richtig, das tun sie. Du kannst die Web Component im CSS auswählen und sie dort festlegen.
Siehe den Pen Web Component mit benutzerdefinierten Eigenschaften von Chris Coyier (@chriscoyier) auf CodePen.
HTML, auf das du über ein Slot verweist, ist global stylable
Wenn du also z.B. hast
<my-module>
<h2 slot="header">My Module</h2>
</my-module>
Und wo du deinen Shadow DOM definierst, verwendest du diesen Header
<div class="module">
<slot name="header"></slot>
</div>
Dann wird der <h2> global stylable sein, aber die <div class="module"> nicht.
Siehe den Pen Slots und Styling von Web Components von Chris Coyier (@chriscoyier) auf CodePen.
::part und ::theme
Ich habe das nicht zu sehr untersucht, da dies eine Spezifikation ist, an der noch gearbeitet wird, aber sie wird wahrscheinlich letztendlich eine große Rolle spielen. Monica Dinculescu behandelt sie im Detail in ihrem Artikel ::part und ::theme, ein ::explainer.
Sieht aus wie eine Möglichkeit, in den Shadow DOM zu gelangen, aber nur auf der genauen Ebene, die übereinstimmt, nicht tiefer.
<h4><x-foo>
#shadow-root
<div part="some-box"><span>...</span></div>
<input part="some-input">
<div>...</div> /* not styleable
</x-foo></h4>
x-foo::part(some-box) { ... }
/* nope */
x-foo::part(some-box) span { ... }
Sehr interessant, dass benutzerdefinierte Eigenschaften durch die Shadow DOM-Grenze zugänglich sind. Die Möglichkeit, Stile richtig zu kapseln, wäre immens nützlich, wird aber leider durch die Tatsache eingeschränkt, dass die Erstellung einer Shadow DOM-Grenze von clientseitigem JavaScript abhängt.
Danke für den Artikel! Ich finde es extrem verwirrend, dass benutzerdefinierte Eigenschaften den Shadow DOM durchdringen können, aber nichts anderes.
Aus irgendeinem Grund habe ich das Gefühl, dass im Zeitalter von Vue.js-ähnlichen Komponenten Web Components obsolet sind, bevor sie richtig implementiert wurden. Es gibt viel Boilerplate und anscheinend scheint das Ganze etwas eigenartig zu sein. Oder vielleicht verstehe ich die Vorteile einfach nicht.
Relevant: Constructable Stylesheets