Der folgende Beitrag ist ein Gastbeitrag von Rob Dodson (@rob_dodson). Rob und ich haben uns im CodePen-Support ausgetauscht, um Polymer (ein Web Components Polyfill, sozusagen) für eine Demo von ihm zum Laufen zu bringen. Wir haben es zum Laufen gebracht, und die Dinge haben sich irgendwie zu diesem Artikel entwickelt. Übernehmen Sie, Rob.
Update: Rob hat diesen Artikel am 5. März 2014 aktualisiert, um alles auf den neuesten Stand zu bringen, da dies derzeit eine ziemlich schnelllebige Technologie ist.
Update: Erneute Aktualisierung am 9. September 2014!
Vor kurzem habe ich mit einem Kunden daran gearbeitet, seine internen Teams im Aufbau von Webanwendungen zu schulen. Während dieses Prozesses wurde mir klar, dass die Art und Weise, wie wir derzeit das Frontend-Frontend-Frontend aufbauen, sehr seltsam und sogar ein wenig kaputt ist. In vielen Fällen kopieren Sie riesige HTML-Teile aus einem Dokument und fügen diese dann in Ihre Anwendung ein (Bootstrap, Foundation usw.) oder Sie streuen jQuery-Plugins über die Seite, die mit JavaScript konfiguriert werden müssen. Dies bringt uns in die eher unglückliche Lage, zwischen aufgeblähtem HTML oder mysteriösem HTML wählen zu müssen, und oft wählen wir beides.
In einem idealen Szenario wäre die HTML-Sprache ausdrucksstark genug, um komplexe UI-Widgets zu erstellen und auch erweiterbar, so dass wir Entwickler Lücken mit eigenen Tags füllen könnten. Heute ist dies durch eine neue Reihe von Standards namens Web Components endlich möglich.
Web Components?
Web Components sind eine Sammlung von Standards, die sich derzeit im W3C in der Entwicklung befinden und nach und nach in Browsern eingeführt werden. Im Wesentlichen ermöglichen sie uns, Markup und Stile zu benutzerdefinierten HTML-Elementen zu bündeln. Was an diesen neuen Elementen wirklich erstaunlich ist, ist, dass sie ihren gesamten HTML- und CSS-Code vollständig kapseln. Das bedeutet, dass die von Ihnen geschriebenen Stile immer wie beabsichtigt gerendert werden und Ihr HTML vor den neugierigen Blicken externer JavaScript geschützt ist.
Wenn Sie mit nativen Web Components experimentieren möchten, empfehle ich die Verwendung von Chrome, da es die beste Unterstützung bietet. Ab Chrome Version 36 ist es der erste Browser, der alle neuen Standards ausliefert.
Praktisches Beispiel
Denken Sie darüber nach, wie Sie derzeit einen Bildschieberegler implementieren, er könnte etwa so aussehen
<div id="slider">
<input checked="" type="radio" name="slider" id="slide1" selected="false">
<input type="radio" name="slider" id="slide2" selected="false">
<input type="radio" name="slider" id="slide3" selected="false">
<input type="radio" name="slider" id="slide4" selected="false">
<div id="slides">
<div id="overflow">
<div class="inner">
<img src="images//rock.jpg">
<img src="images/grooves.jpg">
<img src="images/arch.jpg">
<img src="images/sunset.jpg">
</div>
</div>
</div>
<label for="slide1"></label>
<label for="slide2"></label>
<label for="slide3"></label>
<label for="slide4"></label>
</div>
Siehe den Pen CSS3 Slider von Rob Dodson (@robdodson) auf CodePen
Bildschieberegler adaptiert von CSScience. Bilder mit freundlicher Genehmigung von Eliya Selhub
Das ist ein ordentlicher Batzen HTML, und wir haben noch nicht einmal die CSS hinzugefügt! Aber stellen Sie sich vor, wir könnten all diesen zusätzlichen Ballast entfernen und ihn auf die wichtigen Teile reduzieren. Wie würde das aussehen?
<img-slider>
<img src="images/sunset.jpg" alt="a dramatic sunset">
<img src="images/arch.jpg" alt="a rock arch">
<img src="images/grooves.jpg" alt="some neat grooves">
<img src="images/rock.jpg" alt="an interesting rock">
</img-slider>
Nicht schlecht! Wir haben den Boilerplate-Code entfernt, und der einzige verbleibende Code ist das, was uns wichtig ist. Das ist die Art von Dingen, die Web Components ermöglichen. Aber bevor ich ins Detail gehe, möchte ich Ihnen noch eine Geschichte erzählen.
Im Schatten verborgen
Jahrelang hatten die Browserhersteller einen heimlichen Trick auf Lager. Schauen Sie sich diesen <video>-Tag an und denken Sie wirklich über all die visuellen Schmankerl nach, die Sie mit nur einer Zeile HTML erhalten.
<video src="./foo.webm" controls></video>
Es gibt einen Wiedergabeknopf, einen Schieberegler, Zeitzähler und einen Lautstärkeregler. Viele Dinge, für die Sie keinen Markup schreiben mussten, sie erschienen einfach, als Sie nach <video> gefragt haben.
Aber was Sie tatsächlich sehen, ist eine Illusion. Die Browserhersteller brauchten eine Möglichkeit, zu garantieren, dass die von ihnen implementierten Tags immer gleich gerendert werden, unabhängig von jedem verrückten HTML, CSS oder JavaScript, das wir möglicherweise bereits auf der Seite haben. Um dies zu tun, schufen sie einen geheimen Durchgang, in dem sie ihren Code verstecken und ihn von unseren heißen kleinen Händen fernhalten konnten. Sie nannten diesen geheimen Ort: den Shadow DOM.
Wenn Sie zufällig Google Chrome verwenden, können Sie Ihre Entwicklertools öffnen und die Option Show user agent shadow DOM aktivieren. Dadurch können Sie das <video>-Element detaillierter inspizieren.


Im Inneren finden Sie eine Menge HTML, das alles versteckt ist. Stochern Sie lange genug herum und Sie werden den bereits erwähnten Wiedergabeknopf, den Lautstärkeregler und verschiedene andere Elemente entdecken.
Denken Sie nun an unseren Bildschieberegler zurück. Was wäre, wenn wir alle Zugriff auf den Shadow DOM und die Möglichkeit hätten, unsere eigenen Tags wie <video> zu deklarieren? Dann könnten wir tatsächlich unseren benutzerdefinierten <img-slider>-Tag implementieren und verwenden.
Werfen wir einen Blick darauf, wie das geht, mit der ersten Säule von Web Components, dem Template.
Templates
Jedes gute Bauprojekt muss mit einem Bauplan beginnen, und bei Web Components stammt dieser Bauplan vom neuen <template>-Tag. Der Template-Tag ermöglicht es Ihnen, Markup auf der Seite zu speichern, das Sie später klonen und wiederverwenden können. Wenn Sie bereits mit Bibliotheken wie Mustache oder Handlebars gearbeitet haben, dann sollte sich der <template>-Tag vertraut anfühlen.
<template>
<h1>Hello there!</h1>
<p>This content is top secret :)</p>
</template>
Alles innerhalb eines Templates wird vom Browser als inert betrachtet. Das bedeutet, dass Tags mit externen Quellen—<img>, <audio>, <video> usw.—keine HTTP-Anfragen stellen und <script>-Tags nicht ausgeführt werden. Es bedeutet auch, dass nichts aus dem Template auf der Seite gerendert wird, bis wir es mit JavaScript aktivieren.
Der erste Schritt zur Erstellung unseres <img-slider> ist also, all sein HTML und CSS in ein <template> zu packen.
Siehe den Pen CSS3 Slider Template von Rob Dodson (@robdodson) auf CodePen
Sobald wir das getan haben, sind wir bereit, es in den Shadow DOM zu verschieben.
Shadow DOM
Um wirklich sicherzustellen, dass unser HTML und CSS den Verbraucher nicht negativ beeinflusst, greifen wir manchmal auf iframes zurück. Sie erfüllen ihren Zweck, aber Sie möchten nicht Ihre gesamte Anwendung darin bauen.
Shadow DOM bietet uns die besten Funktionen von iframes, Stil- und Markup-Kapselung, ohne annähernd so viel Ballast.
Um Shadow DOM zu erstellen, wählen Sie ein Element aus und rufen Sie seine Methode createShadowRoot auf. Dies gibt ein Dokumentfragment zurück, das Sie dann mit Inhalt füllen können.
<div class="container"></div>
<script>
var host = document.querySelector('.container');
var root = host.createShadowRoot();
root.innerHTML = '<p>How <em>you</em> doin?</p>'
</script>
Shadow Host
Im Jargon des Shadow DOM wird das Element, auf dem Sie createShadowRoot aufrufen, als Shadow Host bezeichnet. Es ist das einzige Stück, das für den Benutzer sichtbar ist, und hier würden Sie den Benutzer bitten, Ihrem Element Inhalte zur Verfügung zu stellen.
Wenn Sie an unseren <video>-Tag von vorhin denken, ist das <video>-Element selbst der Shadow Host, und die Inhalte sind dieTags, die Sie darin verschachteln.
<video>
<source src="trailer.mp4" type="video/mp4">
<source src="trailer.webm" type="video/webm">
<source src="trailer.ogv" type="video/ogg">
</video>
Shadow Root
Das von createShadowRoot zurückgegebene Dokumentfragment wird als Shadow Root bezeichnet. Die Shadow Root und ihre Nachkommen sind für den Benutzer verborgen, aber sie sind es, die der Browser tatsächlich rendert, wenn er unseren Tag sieht.
Im <video>-Beispiel sind der Wiedergabeknopf, der Schieberegler, die Zeitzähler usw. alles Nachkommen der Shadow Root. Sie erscheinen auf dem Bildschirm, aber ihr Markup ist für den Benutzer nicht sichtbar.
Shadow Boundary
Jegliches HTML und CSS innerhalb der Shadow Root ist durch eine unsichtbare Barriere namens Shadow Boundary vor dem Elterndokument geschützt. Die Shadow Boundary verhindert, dass CSS aus dem Elterndokument in den Shadow DOM eindringt, und sie verhindert auch, dass externes JavaScript in die Shadow Root navigiert.
Übersetzung: Nehmen wir an, Sie haben ein Style-Tag im Shadow DOM, das festlegt, dass alle h3s eine color von Rot haben sollen. Inzwischen gibt es im Elterndokument einen Stil, der festlegt, dass h3s eine color von Blau haben sollen. In diesem Fall werden h3s, die innerhalb des Shadow DOM erscheinen, rot sein, und h3s außerhalb des Shadow DOM werden blau sein. Die beiden Stile werden sich dank unseres Freundes, der Shadow Boundary, gegenseitig ignorieren.
Und wenn das Elterndokument zu einem bestimmten Zeitpunkt nach h3s mit $('h3') sucht, verhindert die Shadow Boundary jegliche Erkundung der Shadow Root und die Auswahl gibt nur h3s zurück, die extern zum Shadow DOM sind.
Dieses Maß an Privatsphäre ist etwas, von dem wir jahrelang geträumt und uns darum bemüht haben. Zu sagen, dass es die Art und Weise, wie wir Webanwendungen erstellen, verändern wird, ist eine reine Untertreibung.
Shadowy Sliders
Um unseren img-slider in den Shadow DOM zu bekommen, müssen wir einen Shadow Host erstellen und ihn mit dem Inhalt unseres Templates füllen.
<template>
<!-- Full of slider awesomeness -->
</template>
<div class="img-slider"></div>
<script>
// Add the template to the Shadow DOM
var tmpl = document.querySelector('template');
var host = document.querySelector('.img-slider');
var root = host.createShadowRoot();
root.appendChild(document.importNode(tmpl.content, true));
</script>
In diesem Fall haben wir ein div erstellt und ihm die Klasse img-slider gegeben, damit es als unser Shadow Host dienen kann.
Wir wählen das Template aus und machen eine tiefe Kopie seines Internen mit document.importNode. Diese Internen werden dann an unsere neu erstellte Shadow Root angehängt.
Wenn Sie Chrome verwenden, können Sie dies tatsächlich im folgenden Pen sehen.
Siehe den Pen CSS3 Slider Shadow DOM von Rob Dodson (@robdodson) auf CodePen
Insertion Points
An diesem Punkt ist unser img-slider im Shadow DOM, aber die Bildpfade sind fest kodiert. Genau wie die <source>-Tags, die in <video> verschachtelt sind, möchten wir, dass die Bilder vom Benutzer kommen, also müssen wir sie vom Shadow Host einladen.
Um Elemente in den Shadow DOM zu ziehen, verwenden wir das neue <content>-Tag. Das <content>-Tag verwendet CSS-Selektoren, um Elemente aus dem Shadow Host auszuwählen und in den Shadow DOM zu projizieren. Diese Projektionen werden als Insertion Points bezeichnet.
Wir machen es uns leicht und gehen davon aus, dass der Slider nur Bilder enthält, sodass wir einen Insertion Point mit dem img-Selektor erstellen können.
<template>
...
<div class="inner">
<content select="img"></content>
</div>
</template>
Da wir Inhalte über einen Insertion Point in den Shadow DOM projizieren, müssen wir auch das neue ::content-Pseudoelement verwenden, um unsere CSS zu aktualisieren.
#slides ::content img {
width: 25%;
float: left;
}
Wenn Sie mehr über die neuen CSS-Selektoren und Kombinatoren erfahren möchten, die von Shadow DOM hinzugefügt wurden, werfen Sie einen Blick auf dieses Cheat Sheet, das ich zusammengestellt habe.
Jetzt sind wir bereit, unseren img-slider zu befüllen.
<div class="img-slider">
<img src="images/rock.jpg" alt="an interesting rock">
<img src="images/grooves.jpg" alt="some neat grooves">
<img src="images/arch.jpg" alt="a rock arch">
<img src="images/sunset.jpg" alt="a dramatic sunset">
</div>
Das ist wirklich cool! Wir haben die Menge des vom Benutzer angezeigten Markups stark reduziert. Aber warum hier aufhören? Wir können die Dinge noch weiter treiben und diesen img-slider zu einem eigenen Tag machen.
Custom Elements
Ein eigenes HTML-Element zu erstellen mag einschüchternd klingen, ist aber eigentlich ziemlich einfach. Im Jargon von Web Components ist dieses neue Element ein Custom Element, und die einzigen beiden Anforderungen sind, dass sein Name einen Bindestrich enthalten muss und sein Prototyp von HTMLElement erben muss.
Werfen wir einen Blick darauf, wie das funktionieren könnte.
<template>
<!-- Full of image slider awesomeness -->
</template>
<script>
// Grab our template full of slider markup and styles
var tmpl = document.querySelector('template');
// Create a prototype for a new element that extends HTMLElement
var ImgSliderProto = Object.create(HTMLElement.prototype);
// Setup our Shadow DOM and clone the template
ImgSliderProto.createdCallback = function() {
var root = this.createShadowRoot();
root.appendChild(document.importNode(tmpl.content, true));
};
// Register our new element
var ImgSlider = document.registerElement('img-slider', {
prototype: ImgSliderProto
});
</script>
Die Methode Object.create gibt einen neuen Prototyp zurück, der von HTMLElement erbt. Wenn der Parser unseren Tag im Dokument findet, prüft er, ob eine Methode namens createdCallback vorhanden ist. Wenn er diese Methode findet, führt er sie sofort aus. Dies ist ein guter Ort, um Setup-Arbeiten durchzuführen. Wir erstellen also Shadow DOM und klonen unser Template hinein.
Wir übergeben den Tag-Namen und den Prototyp an eine neue Methode auf dem document namens registerElement, und danach sind wir bereit.
Jetzt, wo unser Element registriert ist, gibt es ein paar verschiedene Möglichkeiten, es zu verwenden. Die erste und einfachste ist, einfach den <img-slider>-Tag irgendwo in unserem HTML zu verwenden. Aber wir können auch document.createElement("img-slider") aufrufen oder den Konstruktor verwenden, der von document.registerElement zurückgegeben und in der Variablen ImgSlider gespeichert wurde. Es bleibt Ihnen überlassen, welchen Stil Sie bevorzugen.
Unterstützung
Die Unterstützung für die verschiedenen Standards, aus denen Web Components bestehen, ist ermutigend und verbessert sich ständig. Diese Tabelle zeigt, wo wir uns derzeit befinden.

Aber lassen Sie sich von der fehlenden Unterstützung in einigen Browsern nicht entmutigen! Die schlauen Köpfe von Mozilla und Google haben hart daran gearbeitet, Polyfill-Bibliotheken zu entwickeln, die die Unterstützung für Web Components in allen modernen Browsern schleichen lassen! Das bedeutet, dass Sie heute mit diesen Technologien experimentieren und den Leuten, die die Spezifikationen schreiben, Feedback geben können. Dieses Feedback ist wichtig, damit wir nicht mit stinkender, schwer zu verwendender Syntax enden.
Schauen wir uns an, wie wir unseren img-slider mit Googles Web Components-Bibliothek Polymer neu schreiben könnten.
Polymer rettet den Tag!
Polymer fügt dem Browser einen neuen Tag hinzu, <polymer-element>, der Templates automatisch in Shadow DOM umwandelt und benutzerdefinierte Elemente für uns registriert. Alles, was wir tun müssen, ist, Polymer den Namen des Tags mitzuteilen und sicherzustellen, dass wir unser Template-Markup einfügen.
Siehe den Pen Polymer Slider von Chris Coyier (@chriscoyier) auf CodePen.
Ich finde es oft einfacher, Elemente mit Polymer zu erstellen, da die Bibliothek viele Annehmlichkeiten bietet. Dazu gehören Zwei-Wege-Bindung zwischen Elementen und Modellen, automatische Knotensuche und Unterstützung für andere neue Standards wie Web Animations. Außerdem sind die Entwickler auf der mailing list polymer-dev äußerst aktiv und hilfsbereit, was großartig ist, wenn man gerade die Grundlagen lernt, und die StackOverflow-Community wächst.
Dies ist nur ein winziges Beispiel dafür, was Polymer leisten kann. Besuchen Sie daher unbedingt die Projektseite und schauen Sie sich auch die Alternative von Mozilla, X-Tag, an.
Probleme
Jeder neue Standard kann kontrovers sein, und im Fall von Web Components scheinen sie besonders polarisierend zu sein. Bevor wir abschließen, möchte ich einige der Rückmeldungen, die ich in den letzten Monaten erhalten habe, zur Diskussion stellen und meine Meinung dazu äußern.
OMG, das ist XML!!!
Ich denke, das, was die meisten Entwickler wahrscheinlich erschreckt, wenn sie Custom Elements zum ersten Mal sehen, ist die Vorstellung, dass das Dokument in einen großen Haufen XML verwandelt wird, bei dem alles auf der Seite einen maßgeschneiderten Tag-Namen hat und wir auf diese Weise das Web praktisch unlesbar machen. Das ist ein valides Argument, also beschloss ich, die Gemüter zu erhitzen und es auf der Polymer-Mailingliste anzusprechen.
Die Hin- und Her-Diskussion ist ziemlich interessant, aber ich denke, der allgemeine Konsens ist, dass wir einfach experimentieren müssen, um zu sehen, was funktioniert und was nicht. Ist es besser und semantischer, einen Tag-Namen wie <img-slider> zu sehen, oder ist unser aktueller "div-Suppen"-Ansatz der einzig richtige Weg? Alex Rusell hat einen sehr nachdenklichen Beitrag zu diesem Thema verfasst, und ich empfehle jedem, sich die Zeit zu nehmen, ihn zu lesen, bevor er sich eine Meinung bildet.
SEO
Derzeit ist unklar, wie gut Crawler Custom Elements und Shadow DOM unterstützen. Das Polymer FAQ besagt
Suchmaschinen befassen sich seit einiger Zeit mit umfangreichen AJAX-basierten Anwendungen. Die Abkehr von JS und mehr Deklarativität ist eine gute Sache und wird im Allgemeinen die Dinge verbessern.
Der Google Webmaster Blog hat kürzlich angekündigt, dass der Google Crawler JavaScript auf Ihrer Seite ausführt, bevor er sie indiziert. Und mit einem Tool wie Fetch as Google können Sie sehen, was der Crawler sieht, während er Ihre Website analysiert. Ein gutes Beispiel ist die Polymer-Website, die mit Custom Elements erstellt wurde und bei Google leicht durchsuchbar ist.
Ein Tipp, den ich von Gesprächen mit Mitgliedern des Polymer-Teams gelernt habe, ist, darauf zu achten, dass der Inhalt Ihres Custom Elements statisch ist und nicht aus einer Datenbindung stammt.
<!-- probably good -->
<x-foo>
Here is some interesting, and searchable content...
</x-foo>
<!-- probably bad -->
<x-foo>
{{crazyDynamicContent}}
</x-foo>
<!-- also probably bad -->
<a href="{{aDynamicLink}}">Click here</a>
Fairerweise muss man sagen, dass dies kein neues Problem ist. AJAX-lastige Seiten befassen sich seit einigen Jahren mit diesem Problem und glücklicherweise gibt es Lösungen.
Barrierefreiheit (Accessibility)
Offensichtlich wird das Thema Zugänglichkeit ziemlich wichtig, wenn wir Markup in geheimen Shadow DOM Sandboxes verstecken. Steve Faulkner hat sich die Zugänglichkeit im Shadow DOM angesehen und schien mit dem zufrieden zu sein, was er fand.
Ergebnisse aus ersten Tests deuten darauf hin, dass die Einbeziehung von ARIA-Rollen, Zuständen und Eigenschaften in Inhalte, die sich vollständig im Shadow DOM befinden, gut funktioniert. Die Barrierefreiheitsinformationen werden über die Barrierefreiheits-API korrekt exponiert. Screenreader können ohne Probleme auf Inhalte im Shadow DOM zugreifen.
Der vollständige Beitrag ist hier verfügbar.
Marcy Sutton* hat ebenfalls einen Beitrag zu diesem Thema verfasst, in dem sie erklärt:
Web Components, einschließlich Shadow DOM, sind barrierefrei, da assistierende Technologien Seiten als gerendert wahrnehmen, was bedeutet, dass das gesamte Dokument als "ein einziger glücklicher Baum" gelesen wird.
* Marcy weist auch darauf hin, dass der von mir in diesem Beitrag erstellte img-slider nicht barrierefrei ist, da unser CSS-Label-Trick ihn für die Tastatur unzugänglich macht. Behalten Sie das im Hinterkopf, wenn Sie ihn in einem Projekt wiederverwenden möchten.
Sicherlich wird es auf dem Weg einige Hindernisse geben, aber das klingt nach einem ziemlich guten Anfang!
Style-Tags? Ähm, nein danke.
Leider funktionieren <link>-Tags nicht innerhalb des Shadow DOM, was bedeutet, dass die einzige Möglichkeit, externe CSS einzubinden, über @import ist. Mit anderen Worten, <style>-Tags sind – vorerst – unvermeidlich.*
Beachten Sie, dass die von uns besprochenen Stile nur für eine Komponente relevant sind, während wir zuvor dazu trainiert wurden, externe Dateien zu bevorzugen, da sie oft unsere gesamte Anwendung beeinflussen. Ist es also so schlimm, ein <style>-Tag in ein Element einzufügen, wenn all diese Stile nur auf diese eine Entität beschränkt sind? Persönlich finde ich es in Ordnung, aber die Option für externe Dateien wäre sehr wünschenswert.
* Es sei denn, Sie verwenden Polymer, das diese Einschränkung mit XHR umgeht.
Jetzt sind Sie dran
Es liegt an uns, herauszufinden, wohin diese Standards gehen und welche Best Practices sie leiten werden. Probieren Sie Polymer aus und schauen Sie sich auch die Alternative von Mozilla, X-Tag, an (die Unterstützung bis hinunter zu Internet Explorer 9 bietet).
Stellen Sie außerdem sicher, dass Sie sich an die Entwickler bei Google und Mozilla wenden, die diese Standards vorantreiben. Unser Feedback ist notwendig, um diese Werkzeuge zu etwas zu formen, das wir alle nutzen wollen.
Obwohl es noch einige Kanten gibt, glaube ich, dass Web Components schließlich einen neuen Stil der Anwendungsentwicklung einläuten werden, etwas, das dem Zusammenstecken von Legosteinen ähnlicher ist, und weniger wie unser aktueller Ansatz, der oft von überschüssigem Boilerplate geplagt wird. Ich bin ziemlich begeistert von der Richtung, in die das alles geht, und ich freue mich auf das, was die Zukunft bringen mag.
Wirklich interessante Sache hier. Ein weiterer Schritt in die modulare Richtung. Gekoppelt mit Element-Queries könnte das ziemlich mächtig sein.
Ein kleiner Fehler: Es scheint, als hätte die Support-Tabelle die falsche Zahl zugeordnet. [Admin-Hinweis]: behoben.
Entschuldigung dafür, Leute. Ich habe gerade eine Nachricht an Chris geschickt. Die Support-Tabelle ist vorerst hier zu finden.
Psst! Die Browser-Support-Tabelle ist das falsche Bild.
Ich interessiere mich schon seit einiger Zeit für Shadow DOM, und dieser Artikel ist ein guter Ausgangspunkt für mich. Ich kann es kaum erwarten zu sehen, wohin wir von hier aus gehen können.
Zur Info, das Browser-Support-Bild kommt als Video Shadow DOM an.
Welcher hat also gerade mehr Unterstützung, x-tags oder polymer? Und warum geben sie uns nicht einfach die Polyfills + die Funktionalität und schließen all die zusätzlichen Elemente aus. Ist der Sinn von Web Components nicht, sich seine eigenen zu schreiben und seine eigene Semantik hinzuzufügen? Oder verstehe ich das falsch. Jedenfalls danke für den Artikel, das hat viele meiner Fragen beantwortet!
X-Tags verwendet einige der Polymer-Polyfills, sodass die beiden Projekte eng miteinander verbunden sind. X-Tags bietet zusätzliche Unterstützung für IE9, daher ist X-Tags Ihre beste Wahl, wenn Sie auf dieser Plattform arbeiten müssen.
Sie können nur mit den Polyfills arbeiten, wenn Sie möchten. Polymer teilt sie in zwei Bereiche auf. platform.js sind alle Polyfills und polymer.js sind all die Framework-Bits (Datenbindung, Dinge dieser Art). Sie können auch die einzelnen Polyfills ausführen, wenn Sie nur ein oder zwei Dinge möchten.
@Rob Dodson Vielen Dank, ich wusste nicht, dass sie so getrennt waren. Ich habe aber noch eine Frage. Selbst wenn sie dir irgendwann erlauben, das Tag für CSS zu verwenden, würdest du wegen der Tatsache, dass der Shadow DOM keine Stile nach außen durchsickern lässt, nicht mehrere davon verwenden müssen und somit eine langsamere Seitenladezeit aufgrund mehrerer Anfragen haben? Oder liege ich falsch/arbeiten sie an einer Lösung dafür.
Der Polymer CodePen rendert sein Ergebnis für mich in Chrome 30 unter Mac OS 10.6.8 nicht.
Das sieht nach einer ausgezeichneten Technologie aus, die auf dem Weg ist! Ich arbeite für eine Online-Universität, und die Kursmedien re-use Komponenten, die gut in dieses Modell passen würden, was die Produktion viel effizienter machen würde.
Ich habe Chrome 30 und es funktioniert für mich. Obwohl ich es einmal leer angezeigt sah. Muss vielleicht aktualisieren.
Du gibst an, dass es hierfür keine Unterstützung in IE gibt, aber dein non-Polymer CodePen funktioniert in IE 11 einwandfrei. Was ist also die IE-Support-Story?
Hm, das ist seltsam...
Microsoft hat meines Wissens keine der Spezifikationen implementiert. Ich habe mit MS-Leuten darüber gesprochen, und sie haben auch öffentlich getwittert, dass sie Web Components im Auge behalten, aber noch keine Pläne zur Implementierung haben. Ich denke, du kannst ihre Unterstützung für Shadow DOM hier verfolgen.
Es könnte sein, dass IE11 das Template-Tag als HTMLUnknownElement behandelt und es ignoriert. Dann wendet es den Rest der Stile auf die Tags innerhalb davon an. Ich habe keine Kopie von IE11 zum Testen, aber wenn das der Fall ist, dann ist es eine zufällige progressive Verbesserung :)
Wie immer eine tolle Zusammenfassung!
Bezüglich SEO werden wir auf polymer-project.org ein Video veröffentlichen, das mehr Inhalt hat als der FAQ-Eintrag. Die aktuelle Antwort ist nicht ausreichend.
Bezüglich Shadow DOM: FWIW, nach meinem letzten Stand haben die Spezifikationsgötter darüber nachgedacht, addStyleSheet() wieder einzuführen. Eine Sache, die Polymer für dich tut, ist die Konvertierung deiner und das Inline-Styling dieser Regeln im Element. Dies erleichtert die Entwicklung und du musst die zusätzlichen Feinheiten von Shadow DOM nicht kennen. Wenn wir von "Polymers Zuckerguss" sprechen, ist das ein großartiges Beispiel. Es macht das Erstellen von Webkomponenten einfacher.
Rob erwähnt, dass CSS nur über ein Style-Tag im Template-Code angewendet werden kann, ohne derzeitige Unterstützung für Link-Tags. Ich weiß, dass es möglich ist, das Shadow DOM (wie die Video-Tag-Steuerelemente etc.) über CSS Pseudo-Element-Selektoren zu verändern, wie in diesem vorherigen Artikel erwähnt. Wäre dies auch für Webkomponenten möglich?
Absolut! Ich habe das Styling des Shadow DOM nicht angesprochen, weil es ein riesiges Thema ist, aber es gibt eine Reihe von Möglichkeiten, dies zu tun. Ich habe ein paar Beiträge zu diesem Thema geschrieben
Styling Shadow DOM Teil 1
Styling Shadow DOM Teil 2
Zuerst einmal ein schöner Artikel!
Du hast die Sicherheit nicht in der Liste der oben genannten Probleme besprochen. Insbesondere kämpfe ich damit zu verstehen, wie Web Components mit dem iframe-Sicherheitsmodell zusammenpassen.
JS-Sicherheit/Isolation: Wenn du Daten hast, die zu einem Drittanbieter-Widget gehören, musst du immer noch ein iframe laden, um JS auszuführen oder auf Speicher zuzugreifen, ohne dass die zugrunde liegende Seite darauf zugreifen kann, richtig?
HTML-Sicherheit/Isolation: Wenn das gerenderte Widget-HTML sensible Informationen enthält, die du nicht der zugrunde liegenden Seite preisgeben möchtest, dann müsstest du es wieder in ein iframe packen. Stimmt das?
Hey Jared,
Ich glaube nicht, dass Web Components etwas Neues in Bezug auf JS- oder HTML-Sicherheit bieten, daher gelten alle von dir zitierten aktuellen Regeln immer noch.
Rob, danke für die Informationen, das ist wirklich aufregend! Du hast mich inspiriert, etwas für IE7 / IE8 zum Laufen zu bringen.
Ich habe einen Proof of Concept für ein mögliches Polyfill / alternative Lösung für ältere Browser erstellt.
Mein Code geht einen völlig anderen Weg als der "Standard", aber was ich erreichen wollte, waren einige der gleichen Endziele, aber in älteren IE-Versionen. Ich habe bisher nur einige Grundlagen implementiert, aber mein Code könnte verbessert werden, um einige der anderen netten Features hinzuzufügen, die du beschrieben hast. Vielleicht kann jemand die nützlichen Teile meines Codes extrahieren und ein komplett browserübergreifend kompatibles Polyfill erstellen.
Würdest du dir das hier ansehen und mir sagen, was du denkst?
http://www.smartmultimedia.com.au/web_components/
Dies ist die einzige HTML-Markup, um die Web-Komponente zu einer Seite hinzuzufügen.
Das ist wirklich cool, aber ich hoffe, die Probleme mit dem
<style>-Tag werden gelöst. Idealerweise möchte ich diese Komponenten immer noch in meiner globalen, minifizierten CSS-Datei mit einer Art speziellem CSS-Selektor stylen.Alter, bester Gravatar überhaupt
Das
<style>-Tag ist hauptsächlich zum Vorteil des Komponentenautors. Der Autor kann eine Reihe von Möglichkeiten anbieten, damit der Konsument hineingreifen und das Element von außen stylen kann. Diese Stile würden dann mit dem Rest des CSS deiner App leben.Ich habe oben im Thread ein paar Links zu zwei Artikeln gepostet, die ich über das Styling von Elementen geschrieben habe. Ich stimme zu, dass es großartig wäre, externe Dateien für alles zu verwenden, und es klingt, als ob die Browserentwickler daran arbeiten, aber es ist wirklich knifflig wegen all der neuen Szenarien, die Shadow DOM und HTML Imports einführen.
Im Allgemeinen ist eine Webkomponente eine Art Blackbox. Styling ist Aufgabe des Autors, aber Anpassung ist möglich. Hier kannst du sehen, wie ich das für meine Komponentenbibliothek mache.
Wird Polymer von allen wichtigen Browsern unterstützt? Ich dachte, es hätte noch keine breite Unterstützung.
Polymer funktioniert in Chrome, FF, Opera, IE 10+ und Safari 6+
Wirklich interessanter Artikel. Ich kann mir HTML-„Bibliotheken“ vorstellen, ähnlich denen, die wir von jQuery kennen.
Aber da dies wahrscheinlich noch lange nicht in IE eingeführt wird, bezweifle ich, dass ich die Gelegenheit haben werde, es zu nutzen.
Da kommen Polymer und X-Tags ins Spiel. Sie sind dafür konzipiert, die Unterstützung in nicht konformen Browsern zu ermöglichen. Ich denke bei beiden Bibliotheken genauso, wie ich an jQuery denke.
Ich liebe diese Art von Dingen! Es wird sehr interessant sein, wenn dies standardisierter wird, aber in der Zwischenzeit kannst du genau diese Art von Dingen durch AngularJS-Direktiven erstellen.
Ja, das stimmt. Ich weiß, dass das Angular-Team sich Web Components ansieht und hoffentlich werden sie sie in zukünftigen Versionen stärker nutzen. Ich kann mir eine Zukunft vorstellen, in der Direktiven durch Komponenten ersetzt werden.
Ich sehe einige Vorteile aus modularer Sicht. Es wird das Teilen von Widgets viel einfacher machen.
Ich bin jedoch etwas besorgt, dass dies dem Aufräumen deines Zimmers entspricht, indem du das Chaos in den Schrank schiebst. „Du kannst es nicht sehen, also ist es sauber, richtig?“ Das Tolle und Schlechte an HTML ist, dass es völlig freiform ist. Außerdem ist es eine sehr fehlerverzeihende Sprache, viele Syntaxfehler werden nicht erkannt.
Ich wäre zuversichtlicher in dieser Lösung, wenn es stärkere Syntaxregeln für den produzierten Code gäbe. So könnten die Leute Web Components mit dem Wissen verwenden, dass ein gewisses Qualitätsniveau vorhanden ist. (Denk an Rails mit dem Mantra „Konvention vor Konfiguration“)
So oder so wird die Entwicklung von Web Components interessant zu beobachten sein.
Das klingt sehr nach XHTML. Dass HTML so fehlerverzeihend ist, ist eine gute Sache! Es ermöglicht vielen Menschen, nicht nur hartgesottenen Programmierern, Informationen einfach zu veröffentlichen und zu teilen.
Aber zu deinem Punkt über Qualität, ich denke, wir haben das jetzt schon in der Welt der JS-Bibliotheken. Wir bevorzugen Bibliotheken, die gut geschrieben, aktiv entwickelt und sauber kodiert sind. Web Components werden nicht anders sein.
Ich verstehe deinen Punkt, Rob, bezüglich strengerer Regeln für HTML. Wie ich in meinem Beitrag erwähnt habe, ist die fehlerverzeihende Natur von HTML Segen und Fluch zugleich. Es kommt ganz auf den Autor an. Und die portable Natur von Web Components ist ansprechend.
Ich verstehe deinen Punkt, dass gute Bibliotheken von selbst an die Oberfläche steigen. Aber mit dem heutigen Crowdsourcing-Denken werden immer noch einige ziemlich schlechte Code-Schnipsel weitergegeben. Ich denke, im Allgemeinen wird sich die Community selbst regulieren, aber ich bin immer noch besorgt, dass wir potenziell schlechten Code maskieren, indem wir ihn einfach verstecken und weniger zugänglich machen.
Ein Problem, das ich bei benutzerdefinierten Elementen sehe, ist, dass es bei neueren Webentwicklern zu Verwirrung führen wird. Wenn sie sich den Quellcode einer Webseite ansehen, woher wissen sie dann, welche Elemente Standard sind und welche benutzerdefiniert? Wir sollten Autoren ermutigen, ein "x-" Präfix vor ihren Elementnamen zu verwenden, um anzuzeigen, dass es sich um nicht standardmäßige HTML-Elemente handelt, oder das vielleicht in der Web Components-Spezifikation vorschreiben.
Außerdem habe ich bemerkt, dass benutzerdefinierte Elemente mit JavaScript erstellt werden. Was ist, wenn der Benutzer JavaScript deaktiviert hat? Sie werden nichts vom benutzerdefinierten Element sehen können. Und wie wird die Benutzererfahrung beim ersten Laden der Seite sein, bevor das JavaScript, das die benutzerdefinierten Elemente erstellt, geladen wurde? Wird der Benutzer zum Beispiel beim
img-slider-Element, bevor das Element geladen und ausgeführt wird, einfach eine Reihe von vierimg-Elementen auf der Seite sehen?Die Spezifikation verlangt, dass alle benutzerdefinierten Elemente einen Bindestrich "-" in ihrem Tag-Namen haben. So erkennst du, dass sie nicht standardmäßig sind. Anfangs versuchten sie, das "x-"-Ding, wenn ich mich recht erinnere, aber Entwickler fanden es nervig, immer wieder "x" schreiben zu müssen, wenn der Bindestrich dasselbe vermitteln würde.
Viele der HTML5-Standards sind stark auf JavaScript angewiesen, daher wirst du ohne es viel mehr als nur Web Components brechen. Ich weiß ehrlich gesagt nicht, ob die Möglichkeit, es in Browsern zu deaktivieren, noch lange bestehen wird. Firefox 23 hat die Möglichkeit in deinen Einstellungen entfernt (obwohl du es glaube ich immer noch in about:flags tun kannst). Wenn deine Benutzer es in großen Mengen deaktivieren, dann möchtest du Web Components wahrscheinlich nicht verwenden.
Ich habe HTML Imports in diesem Beitrag nicht erwähnt, aber ich habe auf meinem Blog darüber geschrieben und Eric Bidelman hat einen Beitrag auf HTML5 Rocks, der sie abdeckt. Typischerweise importierst du Elemente oben auf der Seite mit einem
<link rel="import">Tag. Imports werden wie CSS geladen, daher gibt es kein FOUC.Einfach genial Rob, gefällt mir. Lesenswert.
Permalink zum Kommentar#
Ich war vor einigen Wochen auf dem Treffen in Google Australien. Alex Danilo gab den Link zur Präsentation, die er erklärte. Dachte, das könnte hier auch helfen.
http://alex-webcomponents.appspot.com
Danke Steven. Das ist ein wirklich großartiges Deck, ich habe es vor einiger Zeit benutzt, als ich mich zum ersten Mal mit dem Thema beschäftigt habe. Eine Sache, auf die ich hinweisen werde, ist, dass das
<element>-Tag entfernt wurde, sodass du benutzerdefinierte Elemente nicht mehr auf diese Weise deklarieren kannst. Es war eine große Änderung und viele der Artikel und Präsentationen da draußen verwenden es immer noch, da sich die Spezifikation in so kurzer Zeit stark verändert hat.Ich habe eine Slide-Deck zusammengestellt, die einige der Änderungen verdeutlicht. Insbesondere die Entfernung des
<element>-Tags, die aktualisierte Nomenklatur für Lifecycle-Callbacks und auch die Änderung von ::pseudo zu ::part-Selektoren. Tatsächlich hat sich ::part kürzlich wieder in ^ und ^^ („the hat and the cat“) Selektoren geändert. Ich muss dazu einen Blogbeitrag schreiben und ihn in diesem Kommentar-Thread lassen :)Schöner Beitrag, ich mag solche Dinge, schöner Blog Rob, ich habe einen vollständigen Blog gelesen und sehr interessant und leicht verständlich, sehr gute Arbeit.
Zuerst einmal hast du hier ein sehr gutes HTML-Slider-Beispiel … :)
Ich bin erstaunt, was HTML5 heutzutage leisten kann, und die neuen Webkomponenten, die du hier gezeigt hast, werden es noch verbessern. Ich denke, mit diesen hat der Flash vs. HTML-Krieg endlich einen Gewinner ;)
Danke!
Es ist lange her, seit ich von @key-frame gehört habe, aber ich dachte nicht, dass es so einfach ist, wie gepostet wurde. Ich fühle mich gesegnet, danke Chris für den schönen Beitrag.
Hallo, das ist etwas abseits des Themas, aber ich fragte mich, ob Blogs WYSIWYG-Editoren verwenden oder ob man manuell mit HTML codieren muss.
Ich starte bald einen Blog, habe aber keine Programmierkenntnisse und wollte Rat von jemandem mit Erfahrung einholen.
Jede Hilfe wäre sehr dankbar!
Safari unterstützt Shadow DOM? Bist du sicher? Das widerspricht allen anderen Quellen, die ich finden kann.
Im Mai sprachen sie darüber, den Code aus Webkit zu entfernen, den Code aus Webkit zu entfernen, weil nach der Blink-Trennung kein Port ihn benutzte.
Ja, das ist irgendwie seltsam. Die Methode
webkitCreateShadowRootfunktioniert in aktuellen Versionen von Safari und ermöglicht es dir, Dinge in einem Shadow-Root-Dokumentfragment zu verstecken. Aber wie du richtig bemerkst, gibt es Gespräche darüber, dass das Safari-Team den zugrundeliegenden Code, der dies ermöglicht, entfernen wird. Also funktioniert es technisch heute, aber vielleicht morgen nicht mehr.Ich habe in letzter Zeit einige Gespräche von Apple-Leuten in der Web Apps WG Mailingliste im Zusammenhang mit Custom Elements gesehen, daher hoffe ich, dass sie sich annähern.
Schöner Artikel, danke! Web Components und Shadow DOM klingen großartig, obwohl für mich die Frage die Verschachtelung ist. Wir bauen Komponenten, um uns das Leben zu erleichtern, und wir bauen komplexe Komponenten, indem wir einfachere unendlich zusammensetzen. Ich sehe in diesem Artikel nicht, wie Shadow DOM dafür funktionieren wird.
Hey Tim,
Das
<content>-Tag ermöglicht es dir, Web Components ineinander zu verschachteln und das Ganze so rendern zu lassen, wie du es erwartest. Es gibt auch ein<shadow>-Tag, das wir nicht behandelt haben. Ich bin nicht sehr tief in das Thema eingedrungen, um die Länge des Beitrags zu begrenzen, aber Dominic Cooney und Eric Bidelman erklären diese Themen wirklich gut in ihren HTML5 Rocks-Beiträgen: Shadow DOM 101, Shadow DOM 301Das Interessanteste an ShadowDom ist die CSS-Isolation. CSS-Regeln von Web Components sollten das äußere (und möglicherweise innere) HTML nicht beeinflussen. Was ist mit einer Regel wie
A { color: red !important;}in einer nicht isolierten Web-Komponente? Das war eine der Hauptschwierigkeiten, auf die ich bei der Entwicklung von WebFragments gestoßen bin.Das Verschachteln von Web Components ist auch ohne Shadow DOM möglich, es hängt einfach davon ab, wie es implementiert wird.
Die Leute müssen akzeptieren, dass das völlig in Ordnung ist. Es gibt technisch absolut nichts Falsches daran und es widerspricht nicht einmal den Best Practices.
Toller Artikel. Ich bin jedoch neugierig auf etwas
Im Abschnitt Insertion Points hast du gesagt
Wie würdest du Einfügungen handhaben, wenn du diese Annahme nicht treffen würdest?
Ich denke, wenn du native Web Components verwenden würdest, müsstest du diese Teile in JavaScript erstellen und sie während der createdCallback in die Vorlage einfügen. Oder jede Folie könnte ihre eigene benutzerdefinierte Komponente sein und dann könntest du sie in den
<img-slider>-Tag verschachteln.Wenn du Polymer verwendest, könntest du vielleicht eine Lösung mit template repeat finden.
Also, ich denke, es gibt ein paar Möglichkeiten, dies zu tun. Ich wollte das Beispiel so einfach wie möglich halten, damit es niemanden stolpern lässt. Deshalb habe ich mich entschieden, es auf diese Weise von Hand zu kodieren.
Das dachte ich mir auch... Aber wenn das der Fall ist, bin ich mir noch nicht sicher, wie Web Components besser sind als zum Beispiel jQuery-Plugins. Ich sage nicht, dass das keine coole Sache ist, aber ich denke, Web Components brauchen noch etwas mehr Entwicklung.
Vielleicht ist es nur, dass Web Components noch sehr jung sind, oder vielleicht muss ich mich mehr damit beschäftigen. Auf jeden Fall, danke für den Artikel. Sehr interessant.
Ist es zwingend erforderlich, Web Components nur mit den Bibliotheken Polymers und X-tags zu verwenden?
Hallo! Ich komme aus der Zukunft, um zu sagen: Bitte, bitte tun wir das nicht. Ich arbeite für ein Unternehmen, das vor einiger Zeit diese sogenannten „Widgets“ erstellt hat, die eine Menge Markup/Funktionalität kapseln, mit der Idee, dass man sie einfach in die Seite einfügt und sie funktionieren einfach! Das Problem ist, dass sie nie genau so funktionieren, wie wir es uns wünschen, und wir müssen uns durch viele, viele verschiedene Dateien kämpfen, die alle auf mysteriöse Weise voneinander abhängen. Ich bin voll und ganz dabei, wenn es um das Neueste und Beste in unserer Branche geht, aber diese Blackbox-Funktionalität ist nichts, was wir wollen. Die Wartbarkeit von so etwas ist ein Albtraum. Diese sind *immer* überkonstruiert ... denn, nun ja, der „Benutzer“-Entwickler wird nicht den gesamten Code im Hintergrund sehen, richtig? Falsch. Sie werden es müssen und werden am Ende deinen Namen verfluchen. Lasst uns das gleich im Keim ersticken.
Diese Stimme aus der Zukunft spricht weise.
Hallo Rob, hast du schon mal ein Polymer-Element zu codeopen.io hinzugefügt? Ich würde gerne einen Pen eines Polymer-Elements erstellen, das wir entwickelt haben. Es ist ein kompletter Javascript-Preloader (keine GIF-Animation). https://github.com/Urucas/priloader. Danke
Schnelle Frage, bitte. Und vielleicht habe ich ein wenig zu schnell gelesen / überflogen, aber wenn eine der Kernideen hier Modularität und die Möglichkeit ist, eigene zu erstellen und dann – im Idealfall, nehme ich an – mit anderen zu teilen, gibt es dann nicht Namenskonflikte?
Ähnlich wie beim Präfix x- wie jemand oben erwähnt hat, sollte es eine Vorkehrung geben, um Namensraumprobleme zu vermeiden?
Oder ist das geringfügig und/oder kein Problem und ich bin einfach zu aufgeregt vom Beginn der Weltmeisterschaft, um geradeaus zu denken?