Web components of HTML
Web Components consists of four separate standards. Together they aim to facilitate the creation of reusable and self-contained pieces of HTML (with JavaScript and CSS). Browser support is lacking but can be polyfilled.
Templates
The template tag holds markup that can be used from JavaScript. It provides a browser native alternative to JavaScript templating libraries.
<div class="fact">All birds are animals</div>
<div class="fact">Some animals are dogs</div>
<template id="fact-box">
<h1>Fact</h1>
<p></p>
</template>
<script>
var template = document.querySelector("#fact-box").content;
var facts = document.querySelectorAll(".fact");
[].forEach.call(facts, function(fact) {
var clone = document.importNode(template, true);
clone.querySelector("p").innerHTML = fact.innerHTML;
fact.replaceChild(clone, fact.firstChild);
});
</script>
Shadow DOM
The shadow DOM is a way to create nested DOMs. They can then be styled independently from the rest of the page. The content tag provides a way to enter content into the shadow DOM from the shadow root element.
<div class="fact">All birds are animals</div>
<div class="fact">Some animals are dogs</div>
<template id="fact-box">
<h1>Fact</h1>
<p><content></content></p>
</template>
<script>
var template = document.querySelector("#fact-box").content;
var facts = document.querySelectorAll(".fact");
[].forEach.call(facts, function(fact) {
var clone = document.importNode(template, true);
fact.createShadowRoot().appendChild(clone);
});
</script>
Custom elements
Creating custom elements allow us to name our pieces of HTML. To distinguish user made tags from official tags the former must always contain a hyphen.
<fact-box>All birds are animals</fact-box>
<fact-box>Some animals are dogs</fact-box>
<template id="fact-box">
<h1>Fact</h1>
<p><content></content></p>
</template>
<script>
var template = document.querySelector("#fact-box").content;
var prototype = Object.create(HTMLElement.prototype);
prototype.createdCallback = function() {
var clone = document.importNode(template, true);
this.createShadowRoot().appendChild(clone);
};
document.registerElement("fact-box", {prototype: prototype});
</script>
HTML imports
Finally, with HTML imports, the finished web component can be placed in an HTML file and imported where it is needed.
<head>
<link rel="import" href="fact-box.html">
</head>
<fact-box>All birds are animals</fact-box>
<fact-box>Some animals are dogs</fact-box>
fact-box.html
<template id="fact-box">
<h1>Fact</h1>
<p><content></content></p>
</template>
<script>
var thisDocument = document.currentScript.ownerDocument;
var template = thisDocument.querySelector("#fact-box").content;
var prototype = Object.create(HTMLElement.prototype);
prototype.createdCallback = function() {
var clone = document.importNode(template, true);
this.createShadowRoot().appendChild(clone);
};
document.registerElement("fact-box", {prototype: prototype});
</script>