Eine Einführung in Web Components

Avatar of Caleb Williams
Caleb Williams am

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

Die Front-End-Entwicklung bewegt sich in einem rasanten Tempo. Dies zeigt sich in den unzähligen Artikeln, Tutorials und Twitter-Threads, die den Zustand dessen beklagen, was einst ein ziemlich einfacher Technologie-Stack war. In diesem Artikel werde ich erörtern, warum Web Components ein großartiges Werkzeug sind, um hochwertige Benutzererlebnisse zu liefern, ohne komplizierte Frameworks oder Build-Schritte und ohne das Risiko, obsolet zu werden. In nachfolgenden Artikeln dieser fünfteiligen Serie werden wir tiefer in jede der Spezifikationen eintauchen.

Diese Serie setzt grundlegende Kenntnisse in HTML, CSS und JavaScript voraus. Wenn Sie sich in einem dieser Bereiche schwach fühlen, machen Sie sich keine Sorgen, denn die Erstellung eines benutzerdefinierten Elements vereinfacht viele Komplexitäten in der Front-End-Entwicklung.

Artikelserie

  1. Eine Einführung in Web Components (Dieser Beitrag)
  2. Erstellung wiederverwendbarer HTML-Vorlagen
  3. Creating a Custom Element from Scratch
  4. Kapselung von Stil und Struktur mit Shadow DOM
  5. Fortgeschrittene Werkzeuge für Web Components

Was sind Web Components eigentlich?

Web Components bestehen aus drei separaten Technologien, die zusammen verwendet werden

  1. Benutzerdefinierte Elemente. Ganz einfach gesagt, dies sind voll gültige HTML-Elemente mit benutzerdefinierten Vorlagen, Verhaltensweisen und Tag-Namen (z. B. <one-dialog>), die mit einer Reihe von JavaScript-APIs erstellt wurden. Benutzerdefinierte Elemente sind in der HTML Living Standard Spezifikation definiert.
  2. Shadow DOM. Fähig zur Isolierung von CSS und JavaScript, fast wie ein <iframe>. Dies ist in der Living Standard DOM Spezifikation definiert.
  3. HTML-Vorlagen. Vom Benutzer definierte Vorlagen in HTML, die erst gerendert werden, wenn sie aufgerufen werden. Das <template>-Tag ist in der HTML Living Standard Spezifikation definiert.

Dies sind die Bestandteile der Web Components Spezifikation.

HTML-Module sind wahrscheinlich die vierte Technologie im Stack, aber sie wurde noch in keinem der großen vier Browser implementiert. Das Chrome-Team hat dazu eine Absicht zur Implementierung in einer zukünftigen Version angekündigt.

Web Components sind in allen wichtigen Browsern mit Ausnahme von Microsoft Edge und Internet Explorer 11 generell verfügbar, aber Polyfills existieren, um diese Lücken zu schließen.

Die Bezeichnung einer dieser Technologien als Web Components ist technisch korrekt, da der Begriff selbst etwas überladen ist. Infolgedessen können jede der Technologien unabhängig oder in Kombination mit anderen verwendet werden. Mit anderen Worten, sie sind nicht gegenseitig ausschließend.

Werfen wir einen *kurzen* Blick auf die ersten drei. In anderen Artikeln dieser Serie werden wir uns eingehender mit ihnen beschäftigen.

Benutzerdefinierte Elemente

Wie der Name schon sagt, sind benutzerdefinierte Elemente HTML-Elemente, wie <div>, <section> oder <article>, aber etwas, das wir selbst benennen können und das über eine Browser-API definiert wird. Benutzerdefinierte Elemente sind genau wie diese Standard-HTML-Elemente – Namen in spitzen Klammern – nur dass sie *immer* einen Bindestrich enthalten, wie <news-slider> oder <bacon-cheeseburger>. Zukünftig haben sich die Browserhersteller verpflichtet, keine neuen integrierten Elemente mit einem Bindestrich in ihren Namen zu erstellen, um Konflikte zu vermeiden.

Benutzerdefinierte Elemente enthalten ihre eigene Semantik, ihr eigenes Verhalten, ihre eigene Markup und können über Frameworks und Browser hinweg geteilt werden.

class MyComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<h1>Hello world</h1>`;
  }
}
    
customElements.define('my-component', MyComponent);

Siehe den Pen
Demo benutzerdefinierter Elemente
von Caleb Williams (@calebdwilliams)
auf CodePen.

In diesem Beispiel definieren wir <my-component>, unser ganz eigenes HTML-Element. Zugegebenermaßen tut es nicht viel, aber dies ist der grundlegende Baustein eines benutzerdefinierten Elements. Alle benutzerdefinierten Elemente müssen in irgendeiner Weise von HTMLElement erben, um beim Browser registriert zu werden.

Benutzerdefinierte Elemente existieren ohne Drittanbieter-Frameworks und die Browserhersteller setzen sich für die fortlaufende Abwärtskompatibilität der Spezifikation ein, was fast garantiert, dass Komponenten, die gemäß den Spezifikationen geschrieben wurden, keine brüchigen API-Änderungen erfahren werden. Darüber hinaus können diese Komponenten generell out-of-the-box mit den beliebtesten Frameworks von heute, einschließlich Angular, React, Vue und anderen, mit minimalem Aufwand verwendet werden.

Shadow DOM

Der Shadow DOM ist eine gekapselte Version des DOM. Dies ermöglicht es Autoren, DOM-Fragmente effektiv voneinander zu isolieren, einschließlich allem, was als CSS-Selektor verwendet werden könnte, und den damit verbundenen Stilen. Im Allgemeinen wird jeglicher Inhalt innerhalb des Gültigkeitsbereichs des Dokuments als Light DOM bezeichnet, und alles innerhalb eines Shadow-Roots wird als Shadow DOM bezeichnet.

Bei der Verwendung des Light DOM kann ein Element mit document.querySelector('selector') ausgewählt werden oder indem auf die Kinder eines beliebigen Elements mit element.querySelector('selector') zugegriffen wird. Auf dieselbe Weise können die Kinder eines Shadow-Roots durch Aufruf von shadowRoot.querySelector angesprochen werden, wobei shadowRoot eine Referenz auf das Dokumentfragment ist – der Unterschied besteht darin, dass die Kinder des Shadow-Roots nicht vom Light DOM aus auswählbar sind. Wenn wir beispielsweise einen Shadow-Root mit einem <button> darin haben, würde der Aufruf von shadowRoot.querySelector('button') unseren Button zurückgeben, aber keine Instanz des Dokument-Abfrage-Selectors wird dieses Element zurückgeben, da es zu einer anderen DocumentOrShadowRoot-Instanz gehört. Stilselektoren funktionieren auf die gleiche Weise.

In dieser Hinsicht funktioniert der Shadow DOM ähnlich wie ein <iframe>, bei dem der Inhalt vom Rest des Dokuments abgeschnitten ist; wenn wir jedoch einen Shadow-Root erstellen, haben wir immer noch die volle Kontrolle über diesen Teil unserer Seite, aber auf einen Kontext beschränkt. Dies nennen wir Kapselung.

Wenn Sie jemals eine Komponente geschrieben haben, die dieselbe id wiederverwendet oder sich auf CSS-in-JS-Tools oder CSS-Namensstrategien (wie BEM) stützt, hat Shadow DOM das Potenzial, Ihre Entwicklererfahrung zu verbessern.

Stellen Sie sich folgendes Szenario vor

<div>
  <div id="example">
    <!-- Pseudo-code used to designate a shadow root -->
    <#shadow-root>
      <style>
      button {
        background: tomato;
        color: white;
      }
      </style>
      <button id="button">This will use the CSS background tomato</button>
    </#shadow-root>
  </div>
  <button id="button">Not tomato</button>
</div>

Abgesehen vom Pseudocode von <#shadow-root> (der hier verwendet wird, um die Shadow-Grenze zu kennzeichnen, die kein HTML-Element hat), ist das HTML vollständig gültig. Um einen Shadow-Root an den obigen Knoten anzuhängen, würden wir etwas wie dies ausführen:

const shadowRoot = document.getElementById('example').attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `<style>
button {
  color: tomato;
}
</style>
<button id="button">This will use the CSS color tomato <slot></slot></button>`;

Ein Shadow-Root kann auch Inhalte aus seinem enthaltenden Dokument mittels des <slot>-Elements enthalten. Die Verwendung eines Slots platziert Benutzereingaben aus dem äußeren Dokument an einer bestimmten Stelle in Ihrem Shadow-Root.

Siehe den Pen
Demo zur Stil-Kapselung mit Shadow DOM
von Caleb Williams (@calebdwilliams)
auf CodePen.

HTML-Vorlagen

Das treffend benannte HTML-Element <template> erlaubt es uns, wiederverwendbare Code-Vorlagen innerhalb eines normalen HTML-Flusses zu erstellen, die nicht sofort gerendert werden, aber zu einem späteren Zeitpunkt verwendet werden können.

<template id="book-template">
  <li><span class="title"></span> &mdash; <span class="author"></span></li>
</template>

<ul id="books"></ul>

Das obige Beispiel würde keinen Inhalt rendern, bis ein Skript die Vorlage verarbeitet, den Code instanziiert und dem Browser mitgeteilt hat, was damit zu tun ist.

const fragment = document.getElementById('book-template');
const books = [
  { title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { title: 'A Farewell to Arms', author: 'Ernest Hemingway' },
  { title: 'Catch 22', author: 'Joseph Heller' }
];

books.forEach(book => {
  // Create an instance of the template content
  const instance = document.importNode(fragment.content, true);
  // Add relevant content to the template
  instance.querySelector('.title').innerHTML = book.title;
  instance.querySelector('.author').innerHTML = book.author;
  // Append the instance ot the DOM
  document.getElementById('books').appendChild(instance);
});

Beachten Sie, dass dieses Beispiel eine Vorlage (<template id="book-template">) ohne andere Web Components-Technologie erstellt, was erneut verdeutlicht, dass die drei Technologien im Stack unabhängig oder kollektiv verwendet werden können.

Vermeintlich könnte der Verbraucher eines Dienstes, der die Template-API nutzt, eine Vorlage beliebiger Form oder Struktur schreiben, die zu einem späteren Zeitpunkt erstellt werden könnte. Eine andere Seite auf einer Website könnte denselben Dienst nutzen, aber die Vorlage auf diese Weise strukturieren:

<template id="book-template">
  <li><span class="author"></span>'s classic novel <span class="title"></span></li>
</template>

<ul id="books"></ul>

Siehe den Pen
Vorlagenbeispiel
von Caleb Williams (@calebdwilliams)
auf CodePen.

Das war unsere Einführung in Web Components

Da die Webentwicklung immer komplizierter wird, wird es für Entwickler wie uns sinnvoll sein, immer mehr Entwicklung an die Webplattform selbst zu delegieren, die sich weiterentwickelt hat. Die Spezifikationen für Web Components sind eine Reihe von Low-Level-APIs, die weiter wachsen und sich mit unseren sich entwickelnden Bedürfnissen als Entwickler weiterentwickeln werden.

Im nächsten Artikel werden wir uns genauer mit den HTML-Vorlagen beschäftigen. Danach werden wir eine Diskussion über benutzerdefinierte Elemente und Shadow DOM folgen lassen. Abschließend werden wir alles mit einem Blick auf höherwertige Werkzeuge und die Integration in heutige beliebte Bibliotheken und Frameworks abrunden.

Artikelserie

  1. Eine Einführung in Web Components (Dieser Beitrag)
  2. Erstellung wiederverwendbarer HTML-Vorlagen
  3. Creating a Custom Element from Scratch
  4. Kapselung von Stil und Struktur mit Shadow DOM
  5. Fortgeschrittene Werkzeuge für Web Components