Why you should be using Web Components. And How - DevWeek 2015

145
1 / 145

Transcript of Why you should be using Web Components. And How - DevWeek 2015

Page 1: Why you should be using Web Components. And How - DevWeek 2015

1 / 145

Page 2: Why you should be using Web Components. And How - DevWeek 2015

Why you should be using WebComponents Now. And How.

PHIL @LEGGETTERHead of Evangelism

2 / 145

Page 3: Why you should be using Web Components. And How - DevWeek 2015

What we'll coverWhat are Web Components?State of native supportComponentised Web Apps nowWhy Web Components are the future!

3 / 145

Page 4: Why you should be using Web Components. And How - DevWeek 2015

What we'll coverWhat are Web Components?State of native supportComponentised Web Apps nowWhy Web Components are the future!♥ Eric Bidelman's Google IO 2014 talk ♥

4 / 145

Page 5: Why you should be using Web Components. And How - DevWeek 2015

What are Web Components?

5 / 145

Page 6: Why you should be using Web Components. And How - DevWeek 2015

What are Web Components?Custom ElementsHTML TemplatesShadow DOMHTML Imports

6 / 145

Page 7: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

7 / 145

Page 8: Why you should be using Web Components. And How - DevWeek 2015

<button>Click Me</button> Click Me

<input type="text" /><input type="number" /><input type="password" /> They all look the same

<select> <option>Select Me</option> <option>Dude</option></select>

Select Me

<label>Check Me</label><input type="checkbox" />

Check Me

Right Now - Elements

a, b, blockquote, body, br, code, div, em, fieldset, h1, h2, hr, img, li, ol, p, pre, span,strong, style, table, tr, td, ...

8 / 145

Page 9: Why you should be using Web Components. And How - DevWeek 2015

<header>I'm a header</header> Stuff around sections or grouping content e.g. main, nav,footer, figure, article, aside etc.

<progress />Form improvements e.g. meter, datalist, keygen,

output

<video />

Embedded content e.g. audio, canvas, svg, math

HTML5 Elements

9 / 145

Page 10: Why you should be using Web Components. And How - DevWeek 2015

Elements - Structure & Meaning<!doctype html><html> <head> <meta charset="utf-8" /> <title>HTML Elements</title> <meta name="description" content="" /> <link rel="stylesheet" href="css/stylez.css" /> </head> <body> <nav> <ul> <li><a href="#">Home</a></li> </ul> </nav> <header> <p>Hello world! This (part of) is HTML5 Boilerplate.</p> </header> <main> <article>Ohhhh. Interesting</article> </main> <footer>&copy; me</footer> <script src="js/script.js"></script> </body></html>

10 / 145

Page 12: Why you should be using Web Components. And How - DevWeek 2015

Elements. Arrrgghhh!

12 / 145

Page 13: Why you should be using Web Components. And How - DevWeek 2015

The Solution:

<Custom Elements />

13 / 145

Page 14: Why you should be using Web Components. And How - DevWeek 2015

The Solution:

<Custom Elements />

More than just markupIMHO the most important part of WebComponents

14 / 145

Page 15: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements: A new Gmail<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

15 / 145

Page 16: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements: A new Gmail<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

<header> <img src="img/logo.png" alt="Google Logo" /> <gmail-search /> <gmail-account-strip /> </header>

16 / 145

Page 17: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements: A new Gmail<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

<header> <img src="img/logo.png" alt="Google Logo" /> <gmail-search /> <gmail-account-strip /> </header>

<gmail-side-bar> <nav is="gmail-labels"></nav> <gmail-contacts /> </gmail-sidebar>

17 / 145

Page 18: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements: A new Gmail<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

<header> <img src="img/logo.png" alt="Google Logo" /> <gmail-search /> <gmail-account-strip /> </header>

<gmail-side-bar> <nav is="gmail-labels"></nav> <gmail-contacts /> </gmail-sidebar>

<main> <nav is="gmail-categories"></nav> <gmail-email-list /> </main>

18 / 145

Page 19: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements: A new Gmail<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

<header> <img src="img/logo.png" alt="Google Logo" /> <gmail-search /> <gmail-account-strip /> </header>

<gmail-side-bar> <nav is="gmail-labels"></nav> <gmail-contacts /> </gmail-sidebar>

<main> <nav is="gmail-categories"></nav> <gmail-email-list /> </main>

<gmail-talk /> </body>

19 / 145

Page 20: Why you should be using Web Components. And How - DevWeek 2015

<img src="http://avatars.io/twitter/leggetter" />

<img src="http://avatars.io/facebook/leggetter" />

<img src="http://avatars.io/instagram/leggetter" />

<img src="http://avatars.io/gravatar/[email protected]" />

Start Simple - An Avatar

20 / 145

Page 21: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

21 / 145

Page 22: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

<script>var MyAvatarPrototype = Object.create(HTMLElement.prototype);

22 / 145

Page 23: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

<script>var MyAvatarPrototype = Object.create(HTMLElement.prototype);

MyAvatarPrototype.createdCallback = function() { var username = this.getAttribute('username'); var service = this.getAttribute('service');

23 / 145

Page 24: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

<script>var MyAvatarPrototype = Object.create(HTMLElement.prototype);

MyAvatarPrototype.createdCallback = function() { var username = this.getAttribute('username'); var service = this.getAttribute('service');

var url = 'http://avatars.io/' + service + '/' + username;

24 / 145

Page 25: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

<script>var MyAvatarPrototype = Object.create(HTMLElement.prototype);

MyAvatarPrototype.createdCallback = function() { var username = this.getAttribute('username'); var service = this.getAttribute('service');

var url = 'http://avatars.io/' + service + '/' + username;

var img = document.createElement( 'img' ); img.setAttribute('src', url); this.appendChild(img);};

25 / 145

Page 26: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements

<my-avatar service="twitter" username="leggetter" />

<script>var MyAvatarPrototype = Object.create(HTMLElement.prototype);

MyAvatarPrototype.createdCallback = function() { var username = this.getAttribute('username'); var service = this.getAttribute('service');

var url = 'http://avatars.io/' + service + '/' + username;

var img = document.createElement( 'img' ); img.setAttribute('src', url); this.appendChild(img);};

document.registerElement('my-avatar', { prototype: MyAvatarPrototype});</script>

Define your own elements. 26 / 145

Page 27: Why you should be using Web Components. And How - DevWeek 2015

<my-avatar service="twitter" username="leggetter" />

<my-avatar service="facebook" username="leggetter" />

<my-avatar service="instagram" username="leggetter" />

<my-avatar service="twitter" username="garyshort" />

<my-avatar />

27 / 145

Page 28: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements - Extending

<img is="my-avatar-ext" service="twitter" username="leggetter" />

28 / 145

Page 29: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements - Extending

<img is="my-avatar-ext" service="twitter" username="leggetter" />

<script>var MyAvatarExtPrototype = Object.create(HTMLImageElement.prototype);

29 / 145

Page 30: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements - Extending

<img is="my-avatar-ext" service="twitter" username="leggetter" />

<script>var MyAvatarExtPrototype = Object.create(HTMLImageElement.prototype);

MyAvatarExtPrototype.createdCallback = function() { var username = this.getAttribute('username'), service = this.getAttribute('service'), url = 'http://avatars.io/' + service + '/' + username;

this.setAttribute('src', url);};

30 / 145

Page 31: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements - Extending

<img is="my-avatar-ext" service="twitter" username="leggetter" />

<script>var MyAvatarExtPrototype = Object.create(HTMLImageElement.prototype);

MyAvatarExtPrototype.createdCallback = function() { var username = this.getAttribute('username'), service = this.getAttribute('service'), url = 'http://avatars.io/' + service + '/' + username;

this.setAttribute('src', url);};

document.registerElement('my-avatar-ext', { prototype: MyAvatarExtPrototype, extends: 'img'});</script>

Extending existing elements31 / 145

Page 32: Why you should be using Web Components. And How - DevWeek 2015

Custom Elements - Lifecycle

createdCallbackattachedCallbackdetachedCallbackattributeChangedCallback(attrName,oldVal, newVal)

32 / 145

Page 33: Why you should be using Web Components. And How - DevWeek 2015

Create Elements usingJavaScript

<script>function createPhils() { var tooManyPhils = 104; var phils = 0; do { var el = document.createElement( 'my-avatar' ); el.setAttribute('service', 'twitter'); el.setAttribute('username', 'leggetter'); document.getElementById( 'phils' ).appendChild( el ); ++phils; } while( phils < tooManyPhils );}</script>

Create Phils

33 / 145

Page 34: Why you should be using Web Components. And How - DevWeek 2015

Why Custom Elements?

34 / 145

Page 35: Why you should be using Web Components. And How - DevWeek 2015

Templates

Native HTML TemplatingSupport

35 / 145

Page 36: Why you should be using Web Components. And How - DevWeek 2015

<script type="text/x-handlebars-template"> <div class="entry"> <h1>{{title}}</h1> <div>{{body}}</div> </div></script>

36 / 145

Page 37: Why you should be using Web Components. And How - DevWeek 2015

HTML Templates Create Avatar

<template id="my-avatar-template"> <style> .container { background-color: cyan; } <!-- omitted for brevity --> </style> <div class="container"> <img class="avatar" /> <span class="username"></span> <span class="service"></span> </div></template>

37 / 145

Page 38: Why you should be using Web Components. And How - DevWeek 2015

HTML Templates Create Avatar

<template id="my-avatar-template"> <style> .container { background-color: cyan; } <!-- omitted for brevity --> </style> <div class="container"> <img class="avatar" /> <span class="username"></span> <span class="service"></span> </div></template>

var MyAvatarTmplPrototype = Object.create(HTMLElement.prototype);

MyAvatarTmplPrototype.createdCallback = function() { // get attributes & build url

38 / 145

Page 39: Why you should be using Web Components. And How - DevWeek 2015

HTML Templates Create Avatar

<template id="my-avatar-template"> <style> .container { background-color: cyan; } <!-- omitted for brevity --> </style> <div class="container"> <img class="avatar" /> <span class="username"></span> <span class="service"></span> </div></template>

var MyAvatarTmplPrototype = Object.create(HTMLElement.prototype);

MyAvatarTmplPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-template' ).content; var el = document.importNode( content, true );

39 / 145

Page 40: Why you should be using Web Components. And How - DevWeek 2015

HTML Templates Create Avatar

<template id="my-avatar-template"> <style> .container { background-color: cyan; } <!-- omitted for brevity --> </style> <div class="container"> <img class="avatar" /> <span class="username"></span> <span class="service"></span> </div></template>

var MyAvatarTmplPrototype = Object.create(HTMLElement.prototype);

MyAvatarTmplPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-template' ).content; var el = document.importNode( content, true );

el.querySelector( '.avatar' ).setAttribute( 'src', url ); el.querySelector( '.username' ).textContent = username; el.querySelector( '.service' ).textContent = service; this.appendChild( el );};

40 / 145

Page 41: Why you should be using Web Components. And How - DevWeek 2015

HTML Templates Create Avatar

<template id="my-avatar-template"> <style> .container { background-color: cyan; } <!-- omitted for brevity --> </style> <div class="container"> <img class="avatar" /> <span class="username"></span> <span class="service"></span> </div></template>

var MyAvatarTmplPrototype = Object.create(HTMLElement.prototype);

MyAvatarTmplPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-template' ).content; var el = document.importNode( content, true );

el.querySelector( '.avatar' ).setAttribute( 'src', url ); el.querySelector( '.username' ).textContent = username; el.querySelector( '.service' ).textContent = service; this.appendChild( el );};

document.registerElement('my-avatar-tmpl', { prototype: MyAvatarTmplPrototype

41 / 145

Page 42: Why you should be using Web Components. And How - DevWeek 2015

Why native HTML Templates?

Libraries → NativeNative benefitsDocument fragment = lightweightInert until cloned/used

42 / 145

Page 43: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM

DOM/CSS "scoping" /protection

43 / 145

Page 44: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - Already usingit

44 / 145

Page 45: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM SubTrees

Light DOMShadow DOMComposed (rendered) DOM

45 / 145

Page 46: Why you should be using Web Components. And How - DevWeek 2015

Light DOM

<my-custom-element> <q>Hello World</q> <!-- part of my-custom-element's light DOM --></my-custom-element>

46 / 145

Page 47: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM

#document-fragment <!-- everything in here is my-custom-element's shadow DOM --> <span>People say: <content></content></span> <footer>sometimes</footer>

47 / 145

Page 48: Why you should be using Web Components. And How - DevWeek 2015

Rendered DOM

<my-custom-element> <span>People say: <q>Hello World</q></span> <footer>sometimes</footer></my-custom-element>

48 / 145

Page 49: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - Problems itsolves

49 / 145

Page 50: Why you should be using Web Components. And How - DevWeek 2015

Styles <span class="container">Bleed!</span>

<template id="my-avatar-tmpl"> <style> .container { background-color: cyan; } ...

<my-avatar-tmpl service="twitter" username="leggetter" />

Styles Bleed!

Me

Shadow DOM - Problems it solves

50 / 145

Page 51: Why you should be using Web Components. And How - DevWeek 2015

Styles <span class="container">Bleed!</span>

<template id="my-avatar-tmpl"> <style> .container { background-color: cyan; } ...

<my-avatar-tmpl service="twitter" username="leggetter" />

Styles Bleed!

Me

<template id="my-avatar-template"> <div class="container"> <img id="avatar" /> ...</template>

Global DOM e.g. id

attributes

Shadow DOM - Problems it solves

51 / 145

Page 52: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

52 / 145

Page 53: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

<template id="my-avatar-shadow-tmpl"> <style> .container { background-color: red; color: white; } ... </style> <div class="container"> <img id="avatar" /> ... </div></template>

53 / 145

Page 54: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

<template id="my-avatar-shadow-tmpl"> <style> .container { background-color: red; color: white; } ... </style> <div class="container"> <img id="avatar" /> ... </div></template>

var MyAvatarShadowPrototype = Object.create(HTMLElement.prototype);

MyAvatarShadowPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-shadow-tmpl' ).content;

54 / 145

Page 55: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

<template id="my-avatar-shadow-tmpl"> <style> .container { background-color: red; color: white; } ... </style> <div class="container"> <img id="avatar" /> ... </div></template>

var MyAvatarShadowPrototype = Object.create(HTMLElement.prototype);

MyAvatarShadowPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-shadow-tmpl' ).content;

this.shadow = this.createShadowRoot(); this.shadow.appendChild( document.importNode( content, true ) );

55 / 145

Page 56: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

<template id="my-avatar-shadow-tmpl"> <style> .container { background-color: red; color: white; } ... </style> <div class="container"> <img id="avatar" /> ... </div></template>

var MyAvatarShadowPrototype = Object.create(HTMLElement.prototype);

MyAvatarShadowPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-shadow-tmpl' ).content;

this.shadow = this.createShadowRoot(); this.shadow.appendChild( document.importNode( content, true ) );

this.shadow.querySelector( '#avatar' ).setAttribute( 'src', url ); this.shadow.querySelector( '#username' ).textContent = username; this.shadow.querySelector( '#service' ).textContent = service;};

56 / 145

Page 57: Why you should be using Web Components. And How - DevWeek 2015

Shadow DOM - In Action Create DevWeek

<template id="my-avatar-shadow-tmpl"> <style> .container { background-color: red; color: white; } ... </style> <div class="container"> <img id="avatar" /> ... </div></template>

var MyAvatarShadowPrototype = Object.create(HTMLElement.prototype);

MyAvatarShadowPrototype.createdCallback = function() { // get attributes & build url

var content = document.querySelector( '#my-avatar-shadow-tmpl' ).content;

this.shadow = this.createShadowRoot(); this.shadow.appendChild( document.importNode( content, true ) );

this.shadow.querySelector( '#avatar' ).setAttribute( 'src', url ); this.shadow.querySelector( '#username' ).textContent = username; this.shadow.querySelector( '#service' ).textContent = service;};

document.registerElement('my-avatar-shadow', { prototype: MyAvatarShadowPrototype

57 / 145

Page 58: Why you should be using Web Components. And How - DevWeek 2015

Why Shadow DOM?

DOM & CSS ScopingProtection for all: Page and ElementEncapsulation

58 / 145

Page 59: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports

Loading & DependencyManagement

59 / 145

Page 60: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Example

Before

<link rel="stylesheet" href="bootstrap.css" /><link rel="stylesheet" href="fonts.css" /><script src="jquery.js"></script><script src="bootstrap.js"></script><script src="bootstrap-tooltip.js"></script><script src="bootstrap-dropdown.js"></script>

60 / 145

Page 61: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Example

Before

<link rel="stylesheet" href="bootstrap.css" /><link rel="stylesheet" href="fonts.css" /><script src="jquery.js"></script><script src="bootstrap.js"></script><script src="bootstrap-tooltip.js"></script><script src="bootstrap-dropdown.js"></script>

After

<link rel="import" href="bootstrap.html" />

61 / 145

Page 62: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Compositionteam-pusher.html

62 / 145

Page 63: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Compositionteam-pusher.html

<link rel="import" href="my-avatar-import.html" />

63 / 145

Page 64: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Compositionteam-pusher.html

<link rel="import" href="my-avatar-import.html" />

<template id="team-pusher-tmpl"> <style> </style>

<my-avatar-import service="twitter" username="maxthelion" /> <my-avatar-import service="twitter" username="copypastaa" /> ... <my-avatar-import service="twitter" username="leggetter" /></template>

...

64 / 145

Page 65: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Compositionteam-pusher.html

<link rel="import" href="my-avatar-import.html" />

<template id="team-pusher-tmpl"> <style> </style>

<my-avatar-import service="twitter" username="maxthelion" /> <my-avatar-import service="twitter" username="copypastaa" /> ... <my-avatar-import service="twitter" username="leggetter" /></template>

<script> var TeamPusherPrototype = Object.create(HTMLElement.prototype);

TeamPusherPrototype.createdCallback = function() { // Get template, createShadowRoot etc. };

document.registerElement('dunddd-organisers', { prototype: TeamPusherPrototype });</script>

...

65 / 145

Page 66: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - CompositionDemo

<link rel="import" href="assets/team-pusher.html" />

<team-pusher></team-pusher>

66 / 145

Page 67: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - CompositionDemo

<link rel="import" href="assets/team-pusher.html" />

<team-pusher></team-pusher>

maxtheliontwitter

copypastaatwitter

zimbatmtwitter

loicdumastwitter

mdpyetwitter

olga_dukovatwitter

pawel_ledwontwitter

hamchapmantwitter

rumblesantwitter

jamessiddletwitter

willsewell_twitter

leggettertwitter

67 / 145

Page 68: Why you should be using Web Components. And How - DevWeek 2015

HTML Imports - Gotchas /Patterns!

68 / 145

Page 69: Why you should be using Web Components. And How - DevWeek 2015

Get & use document from thecurrentScript

( function( currentScript ) {

var ownerDoc = currentScript.ownerDocument;

} )( document._currentScript || document.currentScript );

69 / 145

Page 70: Why you should be using Web Components. And How - DevWeek 2015

importNode and NOTcloneNode for Template

// Note: use ownerDocvar content = ownerDoc.querySelector( '#my-template' );

var clone = ownerDoc.importNode( content, true );

70 / 145

Page 71: Why you should be using Web Components. And How - DevWeek 2015

You can't <link> into the ShadowDOM

<template> <link rel="stylesheet" href="path/to/style.css" /></template>

71 / 145

Page 72: Why you should be using Web Components. And How - DevWeek 2015

Why Use HTML Imports?Bundle JS/HTML/CSS → single URLBasic dependency management

Sharing & reuseSupports composition

72 / 145

Page 73: Why you should be using Web Components. And How - DevWeek 2015

State of Native Support

73 / 145

Page 74: Why you should be using Web Components. And How - DevWeek 2015

Browsers

Chrome41

Firefox36

Safari 8 IE 10

CustomElements

Y N* N N

Templates Y Y Y N

Shadow DOM Y N* N N

HTML Imports Y N* N N

* Can be enabled in config

74 / 145

Page 75: Why you should be using Web Components. And How - DevWeek 2015

Firefox

https://hacks.mozilla.org/2014/12/mozilla-and-web-components/

“ Mozilla will not ship animplementation of HTML Imports.We expect that once JavaScriptmodules ... is shipped, the way welook at this problem will havechanged.

75 / 145

Page 78: Why you should be using Web Components. And How - DevWeek 2015

Safari?

78 / 145

Page 79: Why you should be using Web Components. And How - DevWeek 2015

All is not Lost

79 / 145

Page 80: Why you should be using Web Components. And How - DevWeek 2015

Browsers - with PolyfillsChrome

42Firefox

36Safari 8 IE 10

CustomElements

Y Y Y Y

Templates Y Y Y Y

Shadow DOM Y Y* Y* Y*

HTML Imports Y Y Y Y

http://webcomponents.org/polyfills

* Shadow DOM Polyfill limitations80 / 145

Page 81: Why you should be using Web Components. And How - DevWeek 2015

Componentised Web Appsnow

81 / 145

Page 82: Why you should be using Web Components. And How - DevWeek 2015

Componentised Web Appsnow - questions?

Should native browser support stop us thinking aboutbuilding componentised web apps?

82 / 145

Page 83: Why you should be using Web Components. And How - DevWeek 2015

Componentised Web Appsnow - questions?

Should native browser support stop us thinking aboutbuilding componentised web apps?

No!

83 / 145

Page 84: Why you should be using Web Components. And How - DevWeek 2015

Componentised Web Appsnow - questions?

Should native browser support stop us thinking aboutbuilding componentised web apps?

No!

Should we be build componentised web apps anyway?

84 / 145

Page 85: Why you should be using Web Components. And How - DevWeek 2015

Componentised Web Appsnow - questions?

Should native browser support stop us thinking aboutbuilding componentised web apps?

No!

Should we be build componentised web apps anyway?

We're already building web apps out ofcomponents right now!

85 / 145

Page 86: Why you should be using Web Components. And How - DevWeek 2015

JavaScript

Libraries & Frameworks

86 / 145

Page 87: Why you should be using Web Components. And How - DevWeek 2015

AngularJS

87 / 145

Page 88: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

88 / 145

Page 89: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

89 / 145

Page 90: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

restrict:"AEC",

90 / 145

Page 91: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

restrict:"AEC",

scope: { service: '@', username: '@' },

91 / 145

Page 92: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

restrict:"AEC",

scope: { service: '@', username: '@' },

template: '<img src="http://avatars.io/' + '{{service}}/{{username}}" />' }; });</script>

<body ng-app="demo">

92 / 145

Page 93: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

restrict:"AEC",

scope: { service: '@', username: '@' },

template: '<img src="http://avatars.io/' + '{{service}}/{{username}}" />' }; });</script>

<body ng-app="demo">

<ng-avatar service="twitter" username="leggetter" />

93 / 145

Page 94: Why you should be using Web Components. And How - DevWeek 2015

AngularJS<script src="js/angular.min.js"></script>

<script>angular.module('demo', []) .directive('ngAvatar', function () { return {

restrict:"AEC",

scope: { service: '@', username: '@' },

template: '<img src="http://avatars.io/' + '{{service}}/{{username}}" />' }; });</script>

<body ng-app="demo">

<ng-avatar service="twitter" username="leggetter" />

94 / 145

Page 95: Why you should be using Web Components. And How - DevWeek 2015

EmberJS

95 / 145

Page 96: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

96 / 145

Page 97: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

97 / 145

Page 98: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

<script src="js/ember.js"></script>

98 / 145

Page 99: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

<script src="js/ember.js"></script>

<script> var App = Ember.Application.create();

App.EmAvatarComponent = Ember.Component.extend({

99 / 145

Page 100: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

<script src="js/ember.js"></script>

<script> var App = Ember.Application.create();

App.EmAvatarComponent = Ember.Component.extend({

url: function () { return 'http://avatars.io/' + this.get( 'service' ) + '/' + this.get( 'username' ); }.property( 'username' , 'service' ) });</script>

100 / 145

Page 101: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

<script src="js/ember.js"></script>

<script> var App = Ember.Application.create();

App.EmAvatarComponent = Ember.Component.extend({

url: function () { return 'http://avatars.io/' + this.get( 'service' ) + '/' + this.get( 'username' ); }.property( 'username' , 'service' ) });</script>

<script type="text/x-handlebars" id="components/em-avatar"> <img {{bind-attr src=url}} /></script>

101 / 145

Page 102: Why you should be using Web Components. And How - DevWeek 2015

EmberJS<script src="js/jquery-1.10.0.min.js"></script>

<script src="js/handlebars.js"></script>

<script src="js/ember.js"></script>

<script> var App = Ember.Application.create();

App.EmAvatarComponent = Ember.Component.extend({

url: function () { return 'http://avatars.io/' + this.get( 'service' ) + '/' + this.get( 'username' ); }.property( 'username' , 'service' ) });</script>

<script type="text/x-handlebars" id="components/em-avatar"> <img {{bind-attr src=url}} /></script>

<script type="text/x-handlebars"> {{em-avatar service="twitter" username="leggetter"}}</script>

http://jsbin.com/fexawujibe/2/edit?html,output102 / 145

Page 104: Why you should be using Web Components. And How - DevWeek 2015

ReactJS<script src="js/react.js"></script><script src="js/JSXTransformer.js"></script>

104 / 145

Page 105: Why you should be using Web Components. And How - DevWeek 2015

ReactJS<script src="js/react.js"></script><script src="js/JSXTransformer.js"></script>

<script type="text/jsx">var ReAvatar = React.createClass({ render: function() { return ( <img src={"http://avatars.io/" + this.props.service + "/" + this.props.username} /> ); }});

105 / 145

Page 106: Why you should be using Web Components. And How - DevWeek 2015

ReactJS<script src="js/react.js"></script><script src="js/JSXTransformer.js"></script>

<script type="text/jsx">var ReAvatar = React.createClass({ render: function() { return ( <img src={"http://avatars.io/" + this.props.service + "/" + this.props.username} /> ); }});

React.renderComponent( <ReAvatar service="twitter" username="leggetter" />, document.querySelector('re-avatar'));</script>

106 / 145

Page 107: Why you should be using Web Components. And How - DevWeek 2015

ReactJS<script src="js/react.js"></script><script src="js/JSXTransformer.js"></script>

<script type="text/jsx">var ReAvatar = React.createClass({ render: function() { return ( <img src={"http://avatars.io/" + this.props.service + "/" + this.props.username} /> ); }});

React.renderComponent( <ReAvatar service="twitter" username="leggetter" />, document.querySelector('re-avatar'));</script>

<re-avatar />

107 / 145

Page 108: Why you should be using Web Components. And How - DevWeek 2015

ReactJS<script src="js/react.js"></script><script src="js/JSXTransformer.js"></script>

<script type="text/jsx">var ReAvatar = React.createClass({ render: function() { return ( <img src={"http://avatars.io/" + this.props.service + "/" + this.props.username} /> ); }});

React.renderComponent( <ReAvatar service="twitter" username="leggetter" />, document.querySelector('re-avatar'));</script>

<re-avatar />

108 / 145

Page 110: Why you should be using Web Components. And How - DevWeek 2015

110 / 145

Page 111: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

111 / 145

Page 112: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

<polymer-element name="po-avatar" attributes="service username">

112 / 145

Page 113: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

<polymer-element name="po-avatar" attributes="service username">

<template> <img src="http://avatars.io/{{service}}/{{username}}" /> </template>

113 / 145

Page 114: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

<polymer-element name="po-avatar" attributes="service username">

<template> <img src="http://avatars.io/{{service}}/{{username}}" /> </template>

<script> Polymer('po-avatar', {}); </script></polymer-element>

114 / 145

Page 115: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

<polymer-element name="po-avatar" attributes="service username">

<template> <img src="http://avatars.io/{{service}}/{{username}}" /> </template>

<script> Polymer('po-avatar', {}); </script></polymer-element>

<po-avatar service="facebook" username="leggetter" />

115 / 145

Page 116: Why you should be using Web Components. And How - DevWeek 2015

Polymer

<script src="webcomponentsjs/webcomponents.min.js"></script><link rel="import" href="polymer/polymer.html">

<polymer-element name="po-avatar" attributes="service username">

<template> <img src="http://avatars.io/{{service}}/{{username}}" /> </template>

<script> Polymer('po-avatar', {}); </script></polymer-element>

<po-avatar service="facebook" username="leggetter" />

116 / 145

Page 117: Why you should be using Web Components. And How - DevWeek 2015

117 / 145

Page 118: Why you should be using Web Components. And How - DevWeek 2015

118 / 145

Page 119: Why you should be using Web Components. And How - DevWeek 2015

Who's Building Componentised WebApps now?

119 / 145

Page 120: Why you should be using Web Components. And How - DevWeek 2015

Who's Building Componentised WebApps now?

Angular, Ember, Backbone, Knockout, React, Web Components withPolyfills, Polymer

You probably are already<ng-avatar service="twitter" username="leggetter" />

vs.

<my-avatar service="twitter" username="leggetter" />

120 / 145

Page 121: Why you should be using Web Components. And How - DevWeek 2015

Examples

From Eric's SlidesGitHubChrome OS

GMail built in PolymerTopeka game built in Polymer

121 / 145

Page 122: Why you should be using Web Components. And How - DevWeek 2015

Why Web Components arethe future!

122 / 145

Page 123: Why you should be using Web Components. And How - DevWeek 2015

1. You're already buildingcomponentised web apps

If you're not, you probablyshould be

123 / 145

Page 124: Why you should be using Web Components. And How - DevWeek 2015

2. Trends & Demand

124 / 145

Page 125: Why you should be using Web Components. And How - DevWeek 2015

Libraries

Alignment toward Web ComponentsAngular - DirectivesEmber - ComponentsKnockout - ComponentsPolymer - build upon Web ComponentsAngular 2...

125 / 145

Page 126: Why you should be using Web Components. And How - DevWeek 2015

126 / 145

Page 127: Why you should be using Web Components. And How - DevWeek 2015

Browser Vendor Support

GoogleOpera - uses BlinkMozillaMicrosoft - ?

previously: HTA & ASP.NET ControlsIn high demand on IE UserVoice

Apple - ?

127 / 145

Page 128: Why you should be using Web Components. And How - DevWeek 2015

128 / 145

In Demand

Page 129: Why you should be using Web Components. And How - DevWeek 2015

3. Encourages good softwaredevelopment

Component-basedDevelopment

129 / 145

Page 130: Why you should be using Web Components. And How - DevWeek 2015

Separation of Concerns<!doctype html><html> <head> <meta charset="utf-8"> <title>A new Gmail?</title> <meta name="description" content=""> </head> <body>

<header> <img src="img/logo.png" alt="Google Logo" /> <gmail-search /> <gmail-account-strip /> </header>

<gmail-side-bar> <nav is="gmail-labels"></nav> <gmail-contacts /> </gmail-sidebar> <main> <nav is="gmail-categories"></nav> <gmail-email-list /> </main>

<gmail-talk /> </body></html>

130 / 145

Page 131: Why you should be using Web Components. And How - DevWeek 2015

Encapsulation

Shadow DOM - Style & DOM encapsulationDoes NOT offer JavaScript protection

Hacky Custom Element

leggettertwitter

Don't click me!

131 / 145

Page 132: Why you should be using Web Components. And How - DevWeek 2015

Loose Coupling

Custom EventsElement API (interface)Existing messaging frameworks

132 / 145

Page 133: Why you should be using Web Components. And How - DevWeek 2015

Custom Events<script> var CustomEventPrototype = Object.create(HTMLElement.prototype); CustomEventPrototype.createdCallback = function() { // Build element ...

this.addEventListener('click', function() { var customEvent = new CustomEvent('cheese'); this.dispatchEvent(customEvent); }.bind(this)); };

// ...

133 / 145

Page 134: Why you should be using Web Components. And How - DevWeek 2015

Custom Events<script> var CustomEventPrototype = Object.create(HTMLElement.prototype); CustomEventPrototype.createdCallback = function() { // Build element ...

this.addEventListener('click', function() { var customEvent = new CustomEvent('cheese'); this.dispatchEvent(customEvent); }.bind(this)); };

// ...

var customEl = document.getElementById('my_custom_ev'); customEl.addEventListener('cheese', function() { alert('cheese fired!'); });</script>

<custom-event-ex id="my_custom_ev"></custom-event-ex>

134 / 145

Page 135: Why you should be using Web Components. And How - DevWeek 2015

Element API Attributes & Methods<script> CustomEventPrototype.startSpin = function() { this.img.classList.toggle('spin'); };

CustomEventPrototype.stopSpin = function() { this.img.classList.toggle('spin'); };

// ...

var spinEl = document.getElementById('spin_el'); spinEl.startSpin();

// ...

spinEl.stopSpin();</script>

<custom-event-ex id="spin_el"></custom-event-ex>

135 / 145

Page 136: Why you should be using Web Components. And How - DevWeek 2015

Supports Change

136 / 145

Page 137: Why you should be using Web Components. And How - DevWeek 2015

Reusability

<link rel="import" href="https://some-cdn.com/my-avatar.html" />

137 / 145

Page 138: Why you should be using Web Components. And How - DevWeek 2015

High Cohesion

myavatar.html├── js/script.js├── css/styles.css└── img/bg.png

138 / 145

Page 139: Why you should be using Web Components. And How - DevWeek 2015

Problems? Solved in thefuture?

HTML ImportsVulcanize | HTTP2

Shared scripts?Cache

Multiple versions?Better Cross-component communication?Allow <link> for CSS in Shadow DOM?

139 / 145

Page 140: Why you should be using Web Components. And How - DevWeek 2015

SummaryCustom Elements - Awesome

140 / 145

Page 141: Why you should be using Web Components. And How - DevWeek 2015

Summary

Custom Elements - Awesome

HTML Templates, Shadow DOM, HTML Imports - Native FTW

141 / 145

Page 142: Why you should be using Web Components. And How - DevWeek 2015

Summary

Custom Elements - Awesome

HTML Templates, Shadow DOM, HTML Imports - Native FTW

You can & are building componentised web apps now

142 / 145

Page 143: Why you should be using Web Components. And How - DevWeek 2015

Summary

Custom Elements - Awesome

HTML Templates, Shadow DOM, HTML Imports - Native FTW

You can & are building componentised web apps now

Trends & "best practice" ♥ Web Components

143 / 145

Page 144: Why you should be using Web Components. And How - DevWeek 2015

Summary

Custom Elements - Awesome

HTML Templates, Shadow DOM, HTML Imports - Native FTW

You can & are building componentised web apps now

Trends & "best practice" ♥ Web Components

Web Components are the future!

144 / 145

Page 145: Why you should be using Web Components. And How - DevWeek 2015

Why you should be using WebComponents Now. And How.

Questions?

leggetter.github.io/web-components-now

PHIL @LEGGETTERHead of Evangelism

145 / 145