This document provides an overview and introduction to web components, including:
- Custom elements allow creating new semantic elements and extending existing ones.
- HTML templates separate markup from logic using the <template> tag.
- Shadow DOM provides encapsulation by separating an element's logical and visual trees.
- HTML imports allow including HTML documents to import custom elements and fragments.
- Web components standards like custom elements, templates, and shadow DOM provide encapsulation, separation of concerns, and other benefits, but browser support is still evolving.
5. Pseudo-semantic HTML
Very poor separation of concerns
A script language expected to behave like a “real” language
Inconsistent browser implementations
A huge variety of target devices and platforms
Modern Web Development
It’s a total freakin’ MESS!
6. Web Components to the Rescue
A set of standards designed to componentize the web
Some general goals:
code reuse,
encapsulation,
SoC
UI
composition,
theming
more
expressive,
semantic
7. Part of the Ecosystem
Shares some features with existing frameworks and libraries
Mustache, Handlebars, Angular, Knockout, and many others
But universal:
HTML5
Standard
Portable
Extensible
And growing fast!
8. The Web Components Standards
•roll your own elementsCustom Elements
•reusable DOM fragmentsHTML Templates
•DOM encapsulationShadow DOM
•load HTML declarativelyHTML Imports
9. The State of Web Components
W3C Working Drafts
Mixed browser support:
http://caniuse.com/#search=web%20components
Polyfills
Polymer X-Tag Bosonic
11. Browsers have only partial support, unpredictable
So we use the webcomponents.js polyfill
> bower install --save webcomponentsjs
Installation
12. Reference the webcomponents.js script in the <head> tag
Make sure it’s the first script
<head>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
</head>
Installation
14. HTML Imports Overview
Include HTML documents in other HTML documents
Can be used to import any HTML
Especially useful with Custom Elements
Replaces old kludges:
IFrame
HTML script element <script type="text/html"></script>
Ajax $(target).load("source.html selector");
15. HTML Imports Lifecycle
The outer HTML is loaded and parsed
After DOMContentLoaded, the polyfill loads the imports
After imports are loaded, HTMLImportsLoaded is fired
After the data is parsed, WebComponentsReady is fired
Polyfill lifecycle is a a bit different from native lifecycle
DOMContentLoaded HTMLImportsLoaded WebComponentsReady
16. Reference the polyfill first
Use the <link rel="import" /> tag to declare an import
Process the import in the HTMLImportsLoaded event handler
<head>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="imported.html" id="content" />
<script>
document.addEventListener('HTMLImportsLoaded', function(e) {
var contentDocument = document.getElementById('content').import;
var content = contentDocument.querySelector('.content');
var cloned = content.cloneNode(true);
</script>
</head>
HTML Imports Overview
17. Additional Notes
Scripts running inside the import can reference the containing
document by calling document.currentScript.ownerDocument
In a polyfilled environment: document._currentScript.ownerDocument
CORS constraints apply to documents imported from other
domains
Don’t forget to clone the nodes you want to import
19. Roll Your Own
Custom Elements make a truly semantic web possible
You can create elements named (almost) any way you want:
Same naming rules as other tags
There must be a dash (“-”) in the name to future-proof the name against
the HTML standard and avoid naming collisions
Custom Elements can also be used to “upgrade” existing
elements and add additional behavior
22. Register the element with prototype and extend
document.registerElement('sela-syllabus', {
prototype: Object.create(HTMLUListElement.prototype),
extends: 'ul'
});
Extend an Existing Element
23. And then associate it with the extended element
<ul is="sela-syllabus"></ul>
Extend an Existing Element
24. Custom Element Callbacks
createdCallback
called when an instance is created
attachedCallback
called when an instance is added to DOM subtree
detachedCallback
called when an instance is removed from a DOM subtree
attributeChangedCallback
called after an attribute value changes
26. Separation of Concerns
Separate the view (HTML/CSS) from its logic (JS)
Represented with the <template> tag
Templates are loaded in an “inert” state
ready to be cloned
scripts don’t run
resources aren’t loaded
Templates can be placed almost anywhere, including imports
27. Put the templated content inside the template element
The template will usually be just part of a custom element
<template id="template">
<style>
...
</style>
<div>
<h1>Web Components</h1>
<img src="http://webcomponents.org/img/logo.svg">
</div>
</template>
Using the <template> tag
28. The template’s container has to import the template.content
node, which does a deep clone
The new element is then added to the DOM and activated
<script>
var template = document.querySelector('#template');
var clone = document.importNode(template.content, true);
var host = document.querySelector('#host');
host.appendChild(clone);
</script>
<div id="host"></div>
Cloning the template
29. Data Binding
Templates do not support data binding
Polymer, X-Tag and other polyfills provide data binding support
31. Understanding the Shadow DOM
Separates a logical tree from a visual tree
(it’s actually more complex, but that’s the general idea)
Provides encapsulation
The Custom Element can hide its own logic internally and expose an API
Makes the element more portable
Elements can be nested inside and outside the shadow DOM
33. Vulcanize
Custom Elements embed multiple resources
Browsers use threads to download
resources, but they only have a few available
threads
Using custom elements can severely
degrade page download performance
Vulcanize can flatten the Web Components
to produce fewer requests
Can be added to a grunt/gulp build
Web Components can be heavy!
HTML
CSS
JavaScript
Nested elements
Media files
34. Web Components represent the baseline for the new web
Provide encapsulation, SoC, UI composition, portability and
extensibility, and lots of other features
Not yet finalized – still Working Draft
A moving target, but there are some production examples
There are actually multiple standards that can be used
independently of each other
Summary