Web Components is an umbrella term for the set of upcoming standards for web development (see the W3C Web Components page). Each on its own, they are a useful contribution to the current toolset of a web developer. But together they form a completely new paradigm of how web applications are created.
Web Components consist of 4 standards proposals:
- Templates
- Shadow DOM
- Custom Elements
- Imports
Templates define reusable parts of DOM. Whatever is in a Template, is not executed until the Template content is actually appended to the DOM. That means <img>
sources are not downloaded, scripts are not executed until neccessary - saving on bandwidth and processing. Also, whatever is in a Template is hidden from querySelector
so the scripts on your page won't accidentaly manipulate the original contents of a Template.
Using Templates is as easy as:
<template id="tpl">
Hello world!
</template>
<script>
var tpl = document.querySelector('#tpl');
tpl.content.querySelector('.name').textContent = "World";
var clone = document.importNode(tpl.content, true);
document.body.appendChild(clone);
</script>
Live code on jsFiddle (use Chrome Canary with Web Platform features enabled)
More info on HTML's New Template Tag by Eric Bidelman.
Shadow DOM provides markup and style encapsulation.
This is a feature that was used by browser vendors for the long time. Let's think of a <video>
tag. It consists of controls like the play button, progress bar and the volume controls. Each of those controls is implemented as a <div>
inside of the <video>
tag that is actually not accessible for the the scripts on the page but is rendered on users screen.
Shadow DOM is a tool that let's the web developer create his own hidden encapsulated markup and styles in the same way in which <video>
controls are made.
The simplest example of using Shadow DOM is:
<button>Push me</button>
<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.innerHTML = 'Do not <content></content>!';
</script>
More info on Shadow DOM 101 by Dominic Cooney.
Custom Elements = Templates + Shadow DOM.
With the combined power of Templates and Shadow DOM you are now in power to create first-class HTML elements that extend the browser.
What is great about Custom Elements, as opposed to, say jQuery plugins, is that being first-class DOM members, the Custom Elements can react to the DOM lifecycle events. That enables them to have a certain behavior when they are added to DOM, their attributes change or they are removed from DOM.
A simple Custom Element can look like that:
<template id="myGravatarTemplate">
<img>
</template>
<my-gravatar email="[email protected]"></my-gravatar>
<script>
function updateImg(img, email) {
img.setAttribute("src", "//www.gravatar.com/avatar/" + SparkMD5.hash(email));
}
var MyGravatarElementPrototype = Object.create(HTMLElement.prototype);
MyGravatarElementPrototype.attributeChangedCallback = function (attributeName, oldVal, newVal) {
if (attributeName == "email") {
updateImg(this.shadowRoot.querySelector('img'), newVal);
}
};
MyGravatarElementPrototype.createdCallback = function () {
var t = document.querySelector('#myGravatarTemplate');
var clone = document.importNode(t.content, true);
updateImg(clone.querySelector('img'), this.getAttribute("email") || "");
this.createShadowRoot().appendChild(clone);
};
var MyGravatarElement = document.registerElement('my-gravatar', {
prototype: MyGravatarElementPrototype
});
</script>
More info on Custom Elements - defining new elements in HTML by Eric Bidelman.
Imports load external resources, such as Templates or Custom Elements.
Assuming the above Custom Element definition is contained in a file my-gravatar.html
, the following code will bring the avatar image on screen:
<link rel="import" href="my-gravatar.html">
<my-gravatar email="[email protected]"></my-gravatar>
Imported HTML files can contain templates, stylesheets and scripts. They get executed when the import is loaded.
These are the fundamentals of Web Components. So far, I have only presented usage of native APIs already implemented in Google Chrome Canary. With Polymer, the same code will work in any modern browser and may be simplified with some powerful syntactic sugar. I will cover that in the following blog posts.
There is
<span>
missing in Templates example: https://gist.github.com/tomalec/9534496