SlideShare a Scribd company logo
WEBCOMPONENTS
@marcbaechinger
‚web development is overly complex…‘
unknown, but desperate software engineer
lack of encapsulation and abstraction
TODAYS STANDARDS BODY
STANDARDS BODY
W3C webcomponents
STANDARDS BODY
W3C webcomponents
heavily in flux
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
heavily in flux
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
heavily in flux
2013: same for x-tags and polymer
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
wrapper API (JS/HTML)
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
wrapper API (JS/HTML)
element sets (accordion, …)
http://www.w3.org/TR/components-intro/
Templates
Custom elements
Shadow DOM
Imports
June 2013
BROWSER SUPPORT
polymer
BROWSER SUPPORT
x-tags
polymer
HTML IMPORTS
imports.html
<link href="../styles/import.css" rel="stylesheet"/> 

<section id="root">

<h1>Caption of import</h1>

<p>imported text<p>

</section>

<script>

(function (global) {

global.markup = {

hi: function () {

console.log("hi from a fun declared in an import");

}

};

}(this));

</script>
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
var link = __.e("#markup");

var markup = link.import;

var fragment = markup.querySelector("#root");
access import
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
var link = __.e("#markup");

var markup = link.import;

var fragment = markup.querySelector("#root");
access import
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
usually cloned before use
HTML IMPORTS
HTML IMPORTS
check for import property to feature test
SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

executed once when imported
SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

parent global context
executed once when imported
NO PARENT DOCUMENT!
<script>

var importDoc = 

document.currentScript.ownerDocument;



var parentDocument = document;

</script>

part of the imports.html
NO PARENT DOCUMENT!
<script>

var importDoc = 

document.currentScript.ownerDocument;



var parentDocument = document;

</script>

part of the imports.html
so scripts behave the same as in parent doc
TEMPLATES
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
lazy loaded
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
executed each time when applied
lazy loaded
FEATURETEST
function supportsTemplate() {

var el = document.createElement('template');

return !!('content' in el);

}
read-only DocumentFragment
INSERTING ATEMPLATE
var tmpl = __.e("#template"),

target = __.e("#target");



target.appendChild(

document.importNode(tmpl.content, true)

);
IMPORTEDTEMPLATES
// select the import root from the ‚link‘ elem

var importLink = __.e("#import-1").import;

// select the template within the import

var tmpl = __.e("template", importLink);
__.e("#target").appendChild(

document.importNode(tmpl.content, true)

);
SHADOW DOM
!
Denn die einen sind im Dunkeln

Und die andern sind im Licht

Und man siehet die im Lichte

Die im Dunkeln sieht man nicht 	

!
aus Mackie Messer von Berthold Brecht
RENDERTREE
t e
RENDERTREE
t e
shadow = target.createShadowRoot()
RENDERTREE
t e
shadow = target.createShadowRoot()
RENDERTREE
t e
shadow = target.createShadowRoot()
s
shadow root
RENDERTREE
t e
shadow = target.createShadowRoot() shadow.appendChild(element)
s
shadow root
RENDERTREE
t e
shadow = target.createShadowRoot()
<content/>
shadow.appendChild(element)
s
shadow root
HTML IMPORTS
HTML IMPORTS
initial child node
HTML IMPORTS
initial child node
shadow DOM from template
HTML IMPORTS
initial child node
shadow DOM from template
insertion point of initial content
SHADOW DOMTEMPLATES
function renderShadow(tmplId, targetSelector) {

var tmpl = __.e("#" + tmplId),

target = __.e(targetSelector),

shadow = target.createShadowRoot();



target.style.display = "block";

shadow.appendChild(

tmpl.content.cloneNode(true)

);

}
SHADOW DOMTEMPLATES
function renderShadow(tmplId, targetSelector) {

var tmpl = __.e("#" + tmplId),

target = __.e(targetSelector),

shadow = target.createShadowRoot();



target.style.display = "block";

shadow.appendChild(

tmpl.content.cloneNode(true)

);

}
visually removes all previous children
SHADOW DOMTEMPLATES
<div id="name-shadow-hook" class="hook">

<span class="email">marc.baechinger@gmail.com</span>

<span class="address">Webergasse 23, 8408 Winterthur</span>

<span class="name">Hans Meier</span>

<img src="../images/alaska.jpg" width="480"/>

</div>
<template id="person-template">

<section>

<h3><content select=".name"/></h3>

<p><b>Address</b> <content select=".address"/></p>

<p><b>E-Mail</b> <content select=".email"/></p>

<div><content select=„img"/></div>

</section>

</template>
SHADOW DOMTEMPLATES
<div id="name-shadow-hook" class="hook">

<span class="email">marc.baechinger@gmail.com</span>

<span class="address">Webergasse 23, 8408 Winterthur</span>

<span class="name">Hans Meier</span>

<img src="../images/alaska.jpg" width="480"/>

</div>
<template id="person-template">

<section>

<h3><content select=".name"/></h3>

<p><b>Address</b> <content select=".address"/></p>

<p><b>E-Mail</b> <content select=".email"/></p>

<div><content select=„img"/></div>

</section>

</template>
change initial DOM to change shadow dom
SHADOW DOMTEMPLATES
<template id=„person-template">

<article id="master">

<header><content select=".header"/></header>

<div><content select=".content"/></div>

<footer><content select=".footer"/></footer>

</article>

</template>
template demo
pic: www.lolpig.com
CUSTOM ELEMENTS
<woot/>
CUSTOM ELEMENTS
<polymer-ui-accordion selected="1" id="accordion">

<polymer-ui-collapsible id="abstraction">

<div class="polymer-ui-collapsible-
header">Abstraction and encapsulation</div>

<div>…</div>

</polymer-ui-collapsible>

<polymer-ui-collapsible id="abstraction">

<div class="polymer-ui-collapsible-
header">Abstraction and encapsulation</div>

<div>…</div>

</polymer-ui-collapsible>

</polymer-ui-accordion>
CUSTOM ELEMENTS
CUSTOM ELEMENTS
invisible to querySelector and CSS rules
CUSTOM ELEMENTS
invisible to querySelector and CSS rules
use elements and attributes of DOM as 	

API to interact with the 	

shadow DOM component:

!
acc.setAttribute("selected", 1);
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
returns a constructor
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
returns a constructor
the prototype of the constructor
CALLBACKS
proto.createdCallback = function () {}



proto.attachedCallback = function () {}



proto.detachedCallback = function () {}
proto.attributeChangedCallback = f(name,oldV,newV) {}
CALLBACKS
proto.createdCallback = function () {}



proto.attachedCallback = function () {}



proto.detachedCallback = function () {}
proto.attributeChangedCallback = f(name,oldV,newV) {}
this is the DOM element
CUSTOM ELEMENTS
register(

'x-label', 

{},

{

createdCallback: function() {},

attachedCallback: function() {}

}

);
x-label demo
pic: www.lolpig.com
WEBCOMPONENTS	

RECAP
polyfills to use it today
infrastructure for abstraction and
encapsulation
infrastructure to build frameworks 	

on top of it
heavily pushed by Google
future in the dust
RECAP
BRICK AND POLYMER
POLYMER
POLYMER
polyfill
POLYMER
polyfill
polymer framework (eg. databinding)
POLYMER
polyfill
polymer framework (eg. databinding)
polymer elements
POLYMER
polyfill
polymer framework (eg. databinding)
polymer elementspolymer elements
X-TAGS
X-TAGS API (IMPERATIVE)
MOZILLA.GITHUB.IO/BRICK/
MOZILLA.GITHUB.IO/BRICK/
available elements
MOZILLA.GITHUB.IO/BRICK/
available elements
styles and scripts of Brick
THX, GUYS!
RESOURCES
GENERAL
https://html5-demos.appspot.com/static/webcomponents/index.html	

!
www.html5rocks.com/en/tutorials/webcomponents/customelements/	

!
!
https://developer.mozilla.org/en-US/Apps/Tools_and_frameworks/x-tags
HTML IMPORTS
http://w3c.github.io/webcomponents/spec/imports/

http://www.w3.org/TR/2013/WD-html-imports-20130514/

http://www.w3.org/TR/2014/WD-html-imports-20140311/
http://www.html5rocks.com/en/tutorials/webcomponents/
imports/

http://www.polymer-project.org/platform/html-imports.html
https://bugzilla.mozilla.org/show_bug.cgi?id=877072

http://www.x-tags.org/blog
TEMPLATES
http://www.w3.org/TR/components-intro/#template-
section
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/
spec/templates/index.html
http://www.html5rocks.com/en/tutorials/webcomponents/
template/

More Related Content

What's hot (20)

PDF
Web Components + Backbone: a Game-Changing Combination
Andrew Rota
 
PDF
Google Polymer Framework
Kostas Karolemeas
 
PDF
Intro to html 5
Ian Jasper Mangampo
 
PDF
Web Components & Polymer 1.0 (Webinale Berlin)
Hendrik Ebbers
 
PDF
ActiveDOM
Felix Geisendörfer
 
PDF
The Complementarity of React and Web Components
Andrew Rota
 
PDF
Polymer & the web components revolution 6:25:14
mattsmcnulty
 
PPTX
Introduction to HTML5
Terry Ryan
 
PPSX
Introduction to Html5
www.netgains.org
 
PDF
Chrome enchanted 2015
Chang W. Doh
 
PDF
A brave new web - A talk about Web Components
Michiel De Mey
 
PPTX
New Elements & Features in HTML5
Jamshid Hashimi
 
PDF
HTML5 Essentials
Marc Grabanski
 
PDF
Opening up the Social Web - Standards that are bridging the Islands
Bastian Hofmann
 
PDF
Web Components with Polymer (extra Polymer 2.0)
Dhyego Fernando
 
PDF
Using Ember to Make a Bazillion Dollars
Mike Pack
 
KEY
HTML 5 & CSS 3
Kevin van Dijk
 
ODP
HTML5
Hatem Mahmoud
 
PPTX
Knockout.js
Vivek Rajan
 
PDF
HTML5 Introduction
dynamis
 
Web Components + Backbone: a Game-Changing Combination
Andrew Rota
 
Google Polymer Framework
Kostas Karolemeas
 
Intro to html 5
Ian Jasper Mangampo
 
Web Components & Polymer 1.0 (Webinale Berlin)
Hendrik Ebbers
 
The Complementarity of React and Web Components
Andrew Rota
 
Polymer & the web components revolution 6:25:14
mattsmcnulty
 
Introduction to HTML5
Terry Ryan
 
Introduction to Html5
www.netgains.org
 
Chrome enchanted 2015
Chang W. Doh
 
A brave new web - A talk about Web Components
Michiel De Mey
 
New Elements & Features in HTML5
Jamshid Hashimi
 
HTML5 Essentials
Marc Grabanski
 
Opening up the Social Web - Standards that are bridging the Islands
Bastian Hofmann
 
Web Components with Polymer (extra Polymer 2.0)
Dhyego Fernando
 
Using Ember to Make a Bazillion Dollars
Mike Pack
 
HTML 5 & CSS 3
Kevin van Dijk
 
Knockout.js
Vivek Rajan
 
HTML5 Introduction
dynamis
 

Viewers also liked (20)

PPT
Fsoft Introduction
LONG NGUYEN
 
PDF
Microservices at NewStore
Jan-Oliver Pantel
 
PPTX
The future of web development write once, run everywhere with angular.js and ...
Mark Roden
 
PDF
Future of Web Development
Zeno Rocha
 
PPTX
future of web development
Techberries
 
PDF
Building Isomorphic Apps (JSConf.Asia 2014)
Spike Brehm
 
PDF
Microservices based Application Integration for SaaS, Hybrid Clouds and IoT
Bramh Gupta
 
PDF
Advanced Concepts in Software as a Service / Service Oriented Architecture
Damon Carr
 
PDF
Enterprise DevOps in the Age of Docker & Microservices
XebiaLabs
 
PDF
Full lifecycle of a microservice
Luigi Bennardis
 
PPTX
Chap 5 software as a service (saass)
Raj Sarode
 
PDF
Microservices architecture overview v3
Dmitry Skaredov
 
PDF
SaaS Introduction-May2014
Nguyen Tung
 
PPT
An introduction and overview to Software as a Service
InTechnology Managed Services (part of Redcentric)
 
PPTX
Microservices and the Cloud based future of integration final
BizTalk360
 
PPTX
Multi Tenancy In The Cloud
rohit_ainapure
 
PPTX
Architecting SaaS: Doing It Right the First Time
Serhiy (Serge) Haziyev
 
PDF
Open Architecture for Developing Multitenant Software-as-a-Service Applications
Javier Mijail Espadas Pech
 
PDF
How to build customizable multitenant web applications - IPC11 Spring Edition
Stephan Hochdörfer
 
PPTX
DevOps, containers & microservices: Separating the hype from the reality
Donnie Berkholz
 
Fsoft Introduction
LONG NGUYEN
 
Microservices at NewStore
Jan-Oliver Pantel
 
The future of web development write once, run everywhere with angular.js and ...
Mark Roden
 
Future of Web Development
Zeno Rocha
 
future of web development
Techberries
 
Building Isomorphic Apps (JSConf.Asia 2014)
Spike Brehm
 
Microservices based Application Integration for SaaS, Hybrid Clouds and IoT
Bramh Gupta
 
Advanced Concepts in Software as a Service / Service Oriented Architecture
Damon Carr
 
Enterprise DevOps in the Age of Docker & Microservices
XebiaLabs
 
Full lifecycle of a microservice
Luigi Bennardis
 
Chap 5 software as a service (saass)
Raj Sarode
 
Microservices architecture overview v3
Dmitry Skaredov
 
SaaS Introduction-May2014
Nguyen Tung
 
An introduction and overview to Software as a Service
InTechnology Managed Services (part of Redcentric)
 
Microservices and the Cloud based future of integration final
BizTalk360
 
Multi Tenancy In The Cloud
rohit_ainapure
 
Architecting SaaS: Doing It Right the First Time
Serhiy (Serge) Haziyev
 
Open Architecture for Developing Multitenant Software-as-a-Service Applications
Javier Mijail Espadas Pech
 
How to build customizable multitenant web applications - IPC11 Spring Edition
Stephan Hochdörfer
 
DevOps, containers & microservices: Separating the hype from the reality
Donnie Berkholz
 
Ad

Similar to Introduction to web components (20)

PDF
Michael North "The Road to Native Web Components"
Fwdays
 
PDF
The Road to Native Web Components
Mike North
 
PDF
Introduction to Web Components
Fu Cheng
 
PDF
BreizhBeans - Web components
Horacio Gonzalez
 
PPTX
Polymer and web component
Imam Raza
 
PPTX
Web Components
FITC
 
PPTX
Web Components Revolution
Web Standards School
 
PPTX
Web Components
FITC
 
PDF
Modern Web UI - Web components
Mike North
 
PDF
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
Horacio Gonzalez
 
PDF
The Time for Vanilla Web Components has Arrived
Gil Fink
 
PDF
Polymer 1.0
Cyril Balit
 
PDF
Brownbag on basics of web components
Jason Park
 
PDF
Polymer - pleasant client-side programming with web components
psstoev
 
PDF
Web Components mit Polymer und AngularJS 1.x
inovex GmbH
 
PDF
Web Components mit Polymer und AngularJS 1.x
PatrickHillert
 
PDF
Web Component
偉格 高
 
PPT
Reaching for the Future with Web Components and Polymer
FITC
 
PDF
Client side apps from the future
Chad Hietala
 
PDF
Web components the future is here
Gil Fink
 
Michael North "The Road to Native Web Components"
Fwdays
 
The Road to Native Web Components
Mike North
 
Introduction to Web Components
Fu Cheng
 
BreizhBeans - Web components
Horacio Gonzalez
 
Polymer and web component
Imam Raza
 
Web Components
FITC
 
Web Components Revolution
Web Standards School
 
Web Components
FITC
 
Modern Web UI - Web components
Mike North
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
Horacio Gonzalez
 
The Time for Vanilla Web Components has Arrived
Gil Fink
 
Polymer 1.0
Cyril Balit
 
Brownbag on basics of web components
Jason Park
 
Polymer - pleasant client-side programming with web components
psstoev
 
Web Components mit Polymer und AngularJS 1.x
inovex GmbH
 
Web Components mit Polymer und AngularJS 1.x
PatrickHillert
 
Web Component
偉格 高
 
Reaching for the Future with Web Components and Polymer
FITC
 
Client side apps from the future
Chad Hietala
 
Web components the future is here
Gil Fink
 
Ad

More from Marc Bächinger (8)

PDF
HTML5 unplugged
Marc Bächinger
 
PDF
Modern web application network architecture
Marc Bächinger
 
PDF
JavaScript toolchain
Marc Bächinger
 
PDF
JQuery primer
Marc Bächinger
 
PDF
With your bare hands
Marc Bächinger
 
PDF
Architecting non-trivial browser applications (Jazoon 2012)
Marc Bächinger
 
ODP
Jax-rs-js Tutorial
Marc Bächinger
 
PPTX
Html5 communication
Marc Bächinger
 
HTML5 unplugged
Marc Bächinger
 
Modern web application network architecture
Marc Bächinger
 
JavaScript toolchain
Marc Bächinger
 
JQuery primer
Marc Bächinger
 
With your bare hands
Marc Bächinger
 
Architecting non-trivial browser applications (Jazoon 2012)
Marc Bächinger
 
Jax-rs-js Tutorial
Marc Bächinger
 
Html5 communication
Marc Bächinger
 

Recently uploaded (20)

PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
July Patch Tuesday
Ivanti
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Biography of Daniel Podor.pdf
Daniel Podor
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
July Patch Tuesday
Ivanti
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 

Introduction to web components