Web Components für verschiedene Kontexte erstellen

Avatar of Mattia Astorino
Mattia Astorino am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Dieser Artikel handelt nicht davon, wie man Web Components erstellt. Caleb Williams hat kürzlich bereits einen umfassenden Leitfaden dazu geschrieben. Lassen Sie uns darüber sprechen, wie man mit ihnen arbeitet, was man bei der Erstellung von ihnen berücksichtigen sollte und wie man sie in seine Projekte integriert.

Wenn Sie neu bei Web Components sind, ist Calebs Leitfaden eine großartige Lektüre, aber hier sind weitere Ressourcen, die Sie schnell auf den neuesten Stand bringen

Da Web Components jetzt weit verbreitet unterstützt werden (dank der harten Arbeit vieler Menschen im Hintergrund) — und angesichts des drohenden Wechsels, den Edge zur Chromium-Plattform vollziehen wird — denken die Leute nun über Web Components als „native“ und plattformkonforme Methode nach, um wiederverwendbare UI-Komponenten zu erstellen, um Konsistenz über Designsysteme und Webprojekte hinweg zu gewährleisten, während sie die Kraft des Shadow DOM nutzen, um Stil und Logik innerhalb der Komponente selbst zu kapseln.

Nun, das kann gleichzeitig wahr und falsch sein. Aber lassen Sie uns zuerst das Dreieck der Abstraktionsebenen kennenlernen.

Das Dreieck der Abstraktionsebenen

Technisch gesehen sollten wir Web Components als eine Erweiterung unserer bevorzugten Auszeichnungssprache, HTML (jawohl!), betrachten. Die Web Components API ermöglicht es uns, benutzerdefinierte HTML-Elemente (z. B. <foo-bar>) zu erstellen, die in HTML nicht existieren.

Uns wird gesagt, dass Web Components im Grunde neue HTML-Elemente sind, daher sollten wir sie als Teil der HTML-Spezifikationen betrachten und folglich deren Paradigmen, Kernkonzepte und Nutzung befolgen. Wenn wir all diese Punkte annehmen, werden wir feststellen, dass unsere Komponenten auf den untersten Ebenen des Web-Plattform-Stacks leben werden, neben HTML, CSS und JavaScript.

Frameworks und Bibliotheken wie React, Vue, Angular, SvelteJS arbeiten auf ihrer Abstraktionsebene, direkt über anderen Tools, die in einer Art „mittlerem Reich“ leben, wie StencilJs, Hybrids und Lit. Unter diesen Abstraktionsebenen finden wir unsere grundlegenden Web-Technologien… und Vanilla-Web-Components. Wir können dieses Konzept mit einem ALT (Abstraction Layers Triangle) Diagramm darstellen.

Je höher wir gehen, desto abstrakter werden die Dinge.

Warum ist das wichtig? Nun, es hilft uns, die verschiedenen Ebenen zu visualisieren, die über nativen Komponenten existieren, und den Kontext zu verstehen, in dem sie verwendet werden, damit sie für einen beabsichtigten Kontext erstellt werden können. Was ist Kontext? Dort gehen wir hin.

Gleiche Technologie, unterschiedliche Kontexte

Der Shadow DOM ist ein Schlüsselfaktor in der Web Components API. Er ermöglicht es uns, JavaScript und CSS in einem benutzerdefinierten Element zu bündeln, um sowohl externe Störungen als auch Stilmanipulationen zu verhindern, *es sei denn*, wir erlauben es ausdrücklich. Es gibt tatsächlich einige Ansätze, denen Entwickler folgen können, um zuzulassen, dass externes CSS in den Shadow Root und in eine Komponente „sickert“, einschließlich benutzerdefinierter Eigenschaften und der Pseudo-Elemente ::part und ::theme, was Monica Dinculescu so gut behandelt hat.

Es gibt auch noch etwas anderes zu beachten: den Kontext, mit dem wir arbeiten. Nach drei Jahren persönlicher Entwicklung von Web Components kann ich zwei Kontexte identifizieren: den privaten Kontext (wie ein Designsystem) und den Standard Kontext (wie reines HTML, CSS und JavaScript ohne benutzerdefinierte Stile).

Bevor wir Komponenten entwerfen, müssen wir wissen, wie sie verwendet werden. Daher ist die Bestimmung des Kontexttyps der Schlüssel zu all dem. Der einfachste Weg ist, nur einen Kontext anzusprechen, aber mit einem kleinen CSS-Trick können wir unsere Komponenten für *beide* erstellen.

Betrachten wir die Unterschiede zwischen den beiden Kontexten, bevor wir dazu kommen.

Privater Kontext

Ein privater Kontext ist ein geschlossenes Ökosystem, das Komponenten ihren eigenen Stil zur Verfügung stellt, der so verwendet werden muss, wie er ist. Wenn wir also eine Komponentenbibliothek erstellen, die von spezifischen Styling-Richtlinien oder einem Designsystem stammt, wird jede Komponente benutzerdefinierte Stile widerspiegeln, sodass es nicht notwendig ist, sie jedes Mal zu codieren, wenn sie benötigt werden.

Das kann auch mit JavaScript-Logik der Fall sein. Wir können zum Beispiel einen geschlossenen Shadow Root anhängen, der andere daran hindert, die Shadow-Grenze versehentlich mit querySelector zu durchdringen. Infolgedessen können wir einfach alle Komponenten auswählen und verwenden, wodurch Probleme wie Stilinkonsistenzen und CSS-Kollisionen vermieden werden. Als Autor können Sie auch eine Reihe von CSS-Custom-Properties (oder ::parts) definieren, mit denen eine Komponente für einen bestimmten Anwendungsfall gestylt werden kann, aber dies ist nicht der Fokus eines Designsystems.

Hier ist ein Beispiel für eine Web-Component-Komponente in einem privaten Kontext. Sie enthält alle Stile und Logik innerhalb ihres shadow-root und kann einfach auf jeder Seite platziert werden.

Siehe den Pen
Geschlossene Kontext-Web-Komponente
von Mattia Astorino (@equinusocio)
auf CodePen.

Dieses Beispiel und das folgende sind zu Demonstrationszwecken und nicht für den Produktionseinsatz gedacht, da sie keine wichtigen Situationen wie Barrierefreiheit und andere Optimierungen berücksichtigen.

Komponenten in einem privaten Kontext werden selten außerhalb dieses Kontexts verwendet. Wenn wir zum Beispiel ein Element aus einem Designsystem (das eigene, erzwungene Stile hat) nehmen und es versuchen, es in ein Projekt einzufügen und zu erwarten, es anpassen zu können, ist das schwierig. Sie wissen, wie Bootstrap thematisiert und an Ihre Bedürfnisse angepasst werden kann? Dies ist ziemlich das Gegenteil davon. Diese Komponenten sind dafür gemacht, nur innerhalb ihres Kontexts zu leben.

Standardkontext

Ein Standardkontext kann der komplexeste Komponententyp sein, nicht nur, weil die Umgebung von einem vollwertigen Framework (wie Vue und React) bis zu reinem Vanilla-HTML reichen kann, sondern auch, weil jeder diese Komponente wie jedes andere Element verwenden können sollte.

Wenn Sie beispielsweise eine Komponente öffentlich, z. B. auf npm, veröffentlichen, erwarten die Benutzer, dass sie diese zumindest bis zu einem gewissen Grad anpassen können.

Kennen Sie ein HTML-Element, das seinen eigenen präsentationsbedingten Stil mitbringt? Die Antwort sollte nein sein, denn Elemente müssen explizit mit CSS gestylt werden. Das gilt auch für Web Components, die in einem Standardkontext erstellt wurden. Eine einzelne Web-Komponente sollte durch Hinzufügen von Klassen und Attributen oder anderen Methoden anpassbar sein.

Hier ist dasselbe <todo-list>-Element, das wir im Beispiel für den geschlossenen Kontext gesehen haben, aber für einen Standardkontext konzipiert. Es funktioniert wie erwartet, ohne präsentationsbedingte Stile in seinem Shadow Root. Tatsächlich enthält es nur die erforderliche Logik und Basis-CSS, um sicherzustellen, dass es funktioniert. Ansonsten ist es vollständig anpassbar wie jedes Standard-HTML-Element, wie ein Div.

Siehe den Pen
Standardkontext-Web-Komponente
von Mattia Astorino (@equinusocio)
auf CodePen.

Beide Beispiele, die wir für jeden Kontext betrachtet haben, bestehen aus derselben Komponente. Der Unterschied besteht darin, dass die Komponente im Standardkontext mit externem CSS angepasst und ausgewählt werden kann.

Web Components und Komposition

OK, also die Arbeit mit Web Components ist wirklich dasselbe wie die Arbeit mit reinem HTML, obwohl wir, wie wir gesehen haben, wichtig ist, die Paradigmen und Prinzipien des gegebenen Inhalts zu befolgen. Nun, worauf wir achten müssen, ist die Komposition von Web Components.

Wie von Google Web Fundamentals erklärt

Komposition ist eine der am wenigsten verstandenen Funktionen des Shadow DOM, aber sie ist wohl die wichtigste.

In unserer Welt der Webentwicklung ist Komposition, wie wir Apps deklarativ aus HTML aufbauen. Verschiedene Bausteine (<div>s, <header>s, <form>s, <input>s) kommen zusammen, um Apps zu bilden. Einige dieser Tags arbeiten sogar miteinander. Komposition ist der Grund, warum native Elemente wie <select>, <details>, <form> und <video> so flexibel sind. Jeder dieser Tags akzeptiert bestimmte HTML als Kinder und tut etwas Besonderes damit. Zum Beispiel weiß <select>, wie man option> und <optgroup> in Dropdown- und Mehrfachauswahl-Widgets rendert. Das <details>-Element rendert <summary> als erweiterbaren Pfeil. Sogar <video> weiß, wie man mit bestimmten Kindern umgeht: <source>-Elemente werden nicht gerendert, aber sie beeinflussen das Verhalten des Videos. Welche Magie!

Komposition ist das, was wir normalerweise tun, wenn wir mit HTML arbeiten. Da Web Components lediglich HTML-Elemente mit einer DOM-Referenz sind – und keine logischen Container – sollten wir uns auf Komposition verlassen, um unsere Komponenten und Unterkomponenten zu erstellen. Wenn Sie an ul und select denken, werden Sie feststellen, dass Sie diese Elemente deklarativ komponieren, um das Endergebnis zu erzielen, und Sie haben spezifische Attribute, die mit der Hauptkomponente (z. B. [readonly]) oder der Unterkomponente (z. B. [selected]) verwendet werden. Dies gilt auch für Web Components, und wenn Sie eine benutzerdefinierte Liste erstellen, sollten Sie erwägen, die Hauptkomponente (<custom-list>) und die Kindkomponente (<custom-li>) zu erstellen. Mit dem [slot]-Element können Sie definieren, wo Kindelemente platziert werden sollen, und auch Platzhalterinhalte, die angezeigt werden, wenn keine Kinder übergeben werden.

Web Components und Barrierefreiheit

Eine weitere Sache, die man berücksichtigen muss, ist dieses „kleine“ Thema, das wir Barrierefreiheit nennen. Da wir völlig neue HTML-Elemente erstellen, müssen wir die Barrierefreiheit unserer Elemente berücksichtigen, um eine grundlegende semantische Rolle, jegliche Tastaturnavigation sowie die Präferenzen des Betriebssystems des Benutzers, wie die Einstellungen reduce motion und high contrast, bereitzustellen.

Ich empfehle dringend die folgenden Ressourcen als Referenz für die Erstellung zugänglicher und inklusiver Komponenten, die Definition von semantischem Markup und die Implementierung einer grundlegenden Tastaturnavigation.

Fazit

Web Components sind eine aufstrebende Technologie in der Webentwicklung und es gibt noch keine klar definierten Best Practices, die uns leiten, wenn es darum geht, sie für ihren beabsichtigten oder maximalen Einsatz zu entwickeln. Wenn Sie mit ihnen arbeiten, ist vielleicht das Einzige, was Sie aus diesem Beitrag mitnehmen können, die Überlegung, ob sie für einen geschlossenen Kontext oder einen Standardkontext bestimmt sind, und dann fragen Sie sich WHI

  • Wer wird diese Komponente verwenden?
  • Wie viel Flexibilität sollte diese Person haben, sie anzupassen?
  • Ist diese Komponente für alle oder für eine bestimmte Zielgruppe?