Introduction to
Web
Components
London Polymer Meetup, April 2016
@marco_ciampini
The past
we’re lacking
functional encapsulation within
the Web Platform
Enter
Web Components
!==
Teach new elements
to the browser
Teach new elements
to the browser
HTML
Imports
W3C draft
Custom
Elements
W3C draft
Shadow
DOM
W3C draft
HTML
Templates
W3C spec
Custom Elements
“enabling the author to define and use new types of DOM elements in a document”
W3C draft
Custom tag
<flag-icon country="uk">
</flag-icon>
Type extension
(non normative)
<button is="plastic-button">
Click Me!</button>
Custom Elements
Extend HTMLElement
Are backed by a JS object. Constructor and prototype are defined by the user
Lifecycle callbacks
Observed attributes
class FlagIcon extends HTMLElement {� constructor() {super(); this._countryCode = null;}�� static get observedAttributes() {return ['country'];}�� attributeChangedCallback(name, oldVal, newVal) {� this._countryCode = newVal;
this._updateRendering();� }�� connectedCallback() { this._updateRendering(); }�� get country() { return this._countryCode; }� set country(v) { this.setAttribute('country', v); }�� _updateRendering() {� // Check this.ownerDocument.defaultView, and avoid
// any work if there is no browsing context� }�}��customElements.define('flag-icon', FlagIcon);
Old syntax
New syntax (not implemented yet by browsers)
var proto = Object.create(
HTMLElement.prototype);��proto.createdCallback =
function() {...};�
proto.attachedCallback =
function() {...};�
proto.attributeChangedCallback =
function(name, oldV, newV) {...};�
proto._updateRendering =
function() {...};��var flagIcon =
document.registerElement(
'flag-icon',
{prototype: proto});
HTML Templates
“declare inert HTML subtrees that can be cloned and inserted in the document at runtime”
W3C spec
<template>
[documentFragment]
</template>
[documentFragment]
...
...
[documentFragment]
[documentFragment]
Not
rendered
Rendered
<table>� <tbody>� <template id="row">� <tr><td>Hi</td><td></td></tr>� </template>� </tbody>�</table>��<script>� var data = ['bar', 'foo'];� var template = document.querySelector('#row');� var clone, cells;�� for (var i = 0; i < data.length; i += 1) {� clone = template.content.cloneNode(true);� cells = clone.querySelectorAll('td');� cells[1].textContent = data[i];� template.parentNode.appendChild(clone);� }�</script>
HTML Imports
“a way to include and reuse HTML documents in other HTML documents”
W3C draft
require() for the web
Render blocking if not async
load() and error() events
<link rel="import" href="/imports/file.html">
Shadow DOM
“..combining multiple DOM trees into one hierarchy, and how these trees interact with each other within a document..”
W3C draft
core of the Web Components standards
encapsulate element implementation into a separate DOM tree
DOM APIs (including event retargeting) and styles are scoped within a shadow tree and not accessible by the
host document
Shadow DOM
docu
ment
shadow
host
shadow
root
shadow tree
document tree
Shadow boundaries
hosts
Light DOM
Shadow DOM
Distribution and slotting
“conceptually, slots are holes in a shadow DOM that will be filled by children of its host element”
Bonus Round:
CSS scoping &
CSS variables
W3C draft
@scope, :scope, :scope-context()
Create scoping style rules and access ancestors
:host, :host(), :host-context()
Select shadow host on its normal (Light DOM) context
::content, ::content() (renamed to ::slotted())
Select slot-assigned content
Deprecated:
>>>, ::shadow, /deep/
CSS scoping rules
:root {� --base-text-color: #333; �}��body {� color: var(--base-text-color, black);�}
CSS Variables
:root {� --header-styles: {
font-size: 3em;
margin: 0 auto 2em;
}�}��h1 {� @apply(--header-styles);�}
CSS Mixins
Using Web Components today
| Chrome/ Opera | Firefox | Safari | Edge |
Templates | Stable | Stable | 8 | 13 |
HTML Imports | Stable | On hold | Not considering | Not considering |
Custom Elements | Stable | Flag (unstable) | In development | Prototyping |
Shadow DOM | Stable | Flag (unstable) | Technology Preview | Prototyping |
Browser support
webcomponents.js
All polyfills
webcomponents-lite.js
No Shadow DOM
Shadow DOM polyfill is slow
What’s next
Reworking HTML Imports
Declarative <shadow-dom> ?
Accessibility primitives
CSS parts styling
And more...
Web Components libraries
x-tag
polymer
bosonic
HTML Templates (W3C specification)
Shadow DOM (W3C Editor’s Draft)
HTML Imports (W3C Editor’s Draft)
Custom Element (W3C Editor’s Draft)
CSS Scoping (W3C Editor’s Draft)
Useful links
cheers
@marco_ciampini