Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tomorrow's components, today!

Tomorrow's components, today!

A primer on W3C web components, including HTML imports, shadow dom, custom elements and HTML templates

Mike North

March 11, 2015
Tweet

More Decks by Mike North

Other Decks in Technology

Transcript

  1. 2006 2007 2008 2009 2010 2011 2012 2013 2014 2005

    2004 ES3! ES4! ES5! ES2015! 1999 6! 7! 8! 9! 11! WHERE WE’VE BEEN
  2. THE BROWSER AS AN APPLICATION PLATFORM •  Powerful new language

    standards (TC39) •  Uniting around web standards (W3C) •  Use tomorrow’s technology today (Babel, Web Frameworks)
  3. HTML TEMPLATES What’s the point? •  Get some HTML into

    the DOM, and have it remain inert •  Defer loading of resources •  Defer rendering of content
  4. HTML TEMPLATES <template id="something"> <div class="frame"> <h3 class="title">I am a

    title</h3> <p class="body">I am the body</p> </div> </template> Native
  5. HTML TEMPLATES <template id="something"> <!-- Some style --> <style type="text/css">

    .title { font-size: 24px; } </style> <!-- Some behavior --> <script type="text/javascript"> </script> <!-- Some structure and content --> <div class="frame"> <h3 class="title">I am a title</h3> <p class="body">I am the body</p> </div> </template>
  6. HTML TEMPLATES Add to the DOM Example: http://codepen.io/TrueNorth/pen/xbyVgL?editors=101 // Grab

    the template var tmpl = document.querySelector('#something'); // Add the cloned document fragment to the DOM document.body.appendChild( // Clone the template's document fragment document.importNode(tmpl.content, true) );
  7. SHADOW DOM What’s the point? •  CSS rules bleeding into

    UI components is annoying •  DOM encapsulation is poor, unless you iframe •  Shadow DOM is a subtree within the parent page
  8. SHADOW DOM •  Shadow Root - root element of DOM

    subtree •  Shadow Host - parent of a shadow root Application DOM Component Shadow DOM
  9. SHADOW DOM Creating a Shadow Root // Grab an element

    var elem = document.querySelector("#good-host"); // Create the shadow root var root = elem.createShadowRoot(); // Create a new element var h1 = document.createElement("h1"); h1.innerHTML = "Hello World"; // Append to the shadow root root.appendChild(h1);
  10. SHADOW DOM Add a template to the mix Example: http://codepen.io/TrueNorth/pen/OPBNmq?editors=101

    <template id="something"> <h1>Hello, world!</h1> <p>This is part of my component</p> </template> <div id="good-host"></div> // Grab an element var elem = document.querySelector("#good-host"); // Create the shadow root var root = elem.createShadowRoot(); // Grab the template var tmpl = document.querySelector('#something'); // Add the cloned document fragment to the DOM root.appendChild( // Clone the template's document fragment document.importNode(tmpl.content, true) );
  11. SHADOW DOM Styling •  Style defined/loaded within the shadow DOM

    only applies to shadow DOM •  :host pseudo-selector - for outer element :host { border: 1px solid red; } :host(.hover) { border: 1px solid blue; }
  12. SHADOW DOM Styling •  The ::shadow pseudo-selector penetrates a shadow

    root •  the /deep/ pseudo-selector penetrates all shadow roots
  13. SHADOW DOM Styling .example-host { border: 1px solid purple; padding:

    10px; margin: 10px; } #good-host p { color: blue; } #better-host::shadow p { color: red; } #better-host/deep/ h1 { color: cyan; } <template id="something"> <h1>Hello, world!</h1> <p>This is part of my component</p> <content></content> </template> <div id="good-host" class="example-host"></div> <div id="better-host" class="example-host"> <div id="best-host" class="example-host"></div> </div> Example: http://codepen.io/TrueNorth/pen/MYPyOe
  14. SHADOW DOM Content Projection •  <content> tag to project all

    content •  <content select=“”> to project selected content <template id="something"> <h1><content select=".h1"></content></h1> <p>This is part of my component</p> <content></content> </template> Examples: http://codepen.io/TrueNorth/pen/emPZMv
  15. CUSTOM ELEMENTS What’s the point? •  Compose larger parts of

    an app declaratively •  Provide a standard and consistent life-cycle •  Extensibility
  16. CUSTOM ELEMENTS Registering // Extend a DOM element prototype var

    MegaButtonProto = Object.create(HTMLButtonElement.prototype); // Register your new element type var MegaButton = document.registerElement("mega-button", { prototype: MegaButtonProto, extends: "button" });
  17. CUSTOM ELEMENTS Adding templates // Template var infoBoxTemplate = document.querySelector('#info-pane-template');

    // Register the custom element var InfoBox = document.registerElement("info-pane", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function () { // Create the shadow root this.createShadowRoot() // Add the template to the shadow root .appendChild( document.importNode( infoBoxTemplate.content, true) ); } } }) }); Examples: http://codepen.io/TrueNorth/pen/gbBmMR
  18. HTML IMPORTS •  #include for the web •  onload, onerror

    hooks •  Can include CSS, JS and HTML •  Content can be accessed from the outside •  HTML Imported JS can reference either the main DOM or imported document fragment <link rel="import" href="myfile.html" /> // Get document fragment of an import var content = document .querySelector('link[rel="import"]') .import; // From a <script> included, // with the import access, // imported DOM document .currentScript .ownerDocument .querySelector('.abc');
  19. A REAL USE CASE •  Declarative Syntax •  Responds to

    click •  Content projection •  Style on shadow root <hamburger-menu title="My Menu"> <hb-menu-item href="#abc" caption="Better get on these soon"> Serious Bugs </hb-menu-item> <hb-menu-item href="#def" caption="Oh %#@$!"> Really Serious Bugs </hb-menu-item> </hamburger-menu> Starting Point: http://codepen.io/TrueNorth/pen/PwdLrj Componentized: http://codepen.io/TrueNorth/pen/xbyqME HTML Importified: http://codepen.io/TrueNorth/pen/ogawLm