Shadow DOM

The "Rule of Least Power" suggests choosing the least powerful solution suitable for a given purpose.

http://blog.codinghorror.com/the-principle-of-least-power/

Apps over websites

The component model for the Web

Encapsulation

Clean API

DRY

Portability

a new way of creating jQuery plugins?

"X-Tag and Polymer are both high-level sugar libraries that build upon the W3 Web Components specs - each introduces a different approach to making development of web components an even more amazing experience.

To help make this more relatable, consider the following:

jQuery : DOM :: X-Tag/Polymer : Web Components."

http://www.x-tags.org/blog

"we need to keep our eye on moving on with implementing the core functionality in browsers. Libraries are tools to get things done now. We should allow them to become redundant."

http://christianheilmann.com/2014/04/18/web-components-and-you-dangers-to-avoid/

Shadow DOM

Templates

Custom Elements

HTML Imports

http://jonrimmer.github.io/are-we-componentized-yet/

Shadow DOM

Templates

Custom Elements

HTML Imports

Shadow DOM

Method of establishing and maintaining functional boundaries between DOM trees and how these trees interact with each other within a document, thus enabling better functional encapsulation within the DOM.

Shadow DOM

DOM encapsulation

Style boundaries

Separate form from function

var host = document.querySelector("#host");
var shadowRoot = host.createShadowRoot();
shadowRoot.innerHTML = "shadow!";

Style boundaries

Insertion points

Separate form from function

Event handling

events are retargeted to look like they've come from the host element rather than internal elements to the Shadow DOM.

Shadow DOM

 

Custom Elements

HTML Imports

Templates

Method of declaring a portion of reusable markup that is parsed but not rendered until cloned.

Templates

Shadow DOM

Templates

 

HTML Imports

Custom Elements

Method of defining and using new types of DOM elements in a document.

Custom Elements

var CustomElement = document.registerElement('custom-element');
document.body.appendChild(new CustomElement());
<custom-element></custom-element>

Lifecycle events

AttributeChanged event

Extending elements

progressive enhancement

var CustonButton = document.registerElement('custom-button', {
  prototype: Object.create(HTMLButtonElement.prototype),
  extends: 'button'
});
<button is="custom-button"></button>

Shadow DOM

Templates

Custom Elements

 

HTML Imports

Method of including and reusing HTML documents in other HTML documents.

HTML Imports

DRY principle

Portability

Deduping

<template>
  <style> 
   .sticker {
      font: 30px/1.5 Montserrat, sans-serif;
      border: 4px solid crimson;
      border-radius: 20px;
      width: 400px;
      text-align: center;
      overflow: hidden;
    }
    .label {
      background: crimson;
      margin: 0;
      padding: .5em;
      color: white;
      font-size: .8em;
    }
    .name {
      font-weight: bold;
    }
  </style>
  <div class="sticker">
    <p class="label">Hi, my name is</p>
    <p class="name">
      <content></content>
    </p>
  </div>
</template>

<script>
  
  var NameStickerProto = Object.create(HTMLElement.prototype);
  
  var importDoc = document.currentScript.ownerDocument;

  NameStickerProto.createdCallback = function() {
    
    var shadowRoot = this.createShadowRoot();
    var template = importDoc.querySelector("template");

    shadowRoot.appendChild(template.content);
  };

  var NameSticker = document.registerElement('name-sticker', {
    prototype: NameStickerProto
  });
  
</script>

Can I use it?

http://jonrimmer.github.io/are-we-componentized-yet/

Chrome extensions

platform.jsPolymer

X-Tag

Bosonic

AngularJS

React

Polymer core elements

Paper elements

Mozilla Brick

Customelements.io

Component Kitchen

<google-map latitude="37.77493"
    longitude="-122.41942" fitToMarkers>
  
    <google-map-marker 
        latitude="37.779" longitude="-122.3892"
          draggable="true" title="Go Giants!">
    </google-map-marker>
      <google-map-marker
        latitude="37.777" longitude="-122.38911">
    </google-map-marker>
</google-map>
<core-ajax
    auto
    url="http://gdata.youtube.com/feeds/api/videos/"
    params='{"alt":"json", "q":"chrome"}'
    handleAs="json"
    on-core-response="{{handleResponse}}">
</core-ajax>
<google-analytics
    domain="example.com"
    code="UA-XXXXX-Y">
</google-analytics>
<paper-slider></paper-slider>

Questions?

Iframes :/

new document context

sizing issues

meaningless markup

hard to script into it

BUT it's safer

Shadow DOM

By Anikó Fejes

Shadow DOM

Web Conference Hungary 2014

  • 1,048