# The future with web components ## Ryan Seddon # ME * [@ryanseddon](https://twitter.com/ryanseddon) * [thecssninja.com](http://www.thecssninja.com/) * [Modernizr](http://modernizr.com/) * [SEEK](http://seek.com.au/) # Web Components, what are they * Allow authors to compose re-usable "components"
 <foo-bar></foo-bar>
# Umbrella term * Custom Elements * Shadow DOM * Templates * Imports * Decorators1 1 Not talking about this # What do they solve? * Encapsulation - iframe without baggage * Modularisation * Easy to use # Using a "*component*" today 1. Get jQuery UI widget 1. Include in page. May require CSS, JavaScript 1. Initialise widget through setup code 1. Check to make sure it hasn't broken anything 1. Fix broken things ![](images/kevin-rose-throws-raccoon.gif) Makes you wanna endlessly throw racoons down a stairwell. # The future 1. Import component 1. Use on page

    <link rel="import" href="x-markdown.html" />

    <x-markdown></x-markdown>
    
# Examples * This slide deck is a series of components * x-markdown * x-slideshow * x-slide which extends x-markdown # Important ## All demos use the [Polymer polyfills](http://www.polymer-project.org/) * Things will change, fast * I'll try to keep the slides up-to-date # Custom Elements * Extending existing elements * Creating new ones # Create custom element
<element name="x-reverse">

    </element>

    <x-reverse>
      I put my thing down, flip it and reverse it.
    </x-reverse>Check out this Pen!
# Custom Element Registration * Element definition `this.register()` * `document.register()` # Registering
<element name="x-reverse">
      <script>
        if (this !== window) {
           this.register({
             prototype: {
               readyCallback: function() {
                 this.textContent = this.textContent.split('').reverse().join('');
               }
             }
           });
         }
      </script>
    </element>

    <x-reverse>
      I put my thing down, flip it and reverse it.
    </x-reverse>Check out this Pen!
# document.register()
var btn = document.querySelector("button");

    function register() {
      var proto = Object.create(HTMLElement.prototype);

      proto.readyCallback = function() {
        this.textContent = this.textContent.split('').reverse().join('');
      };

      document.register('x-reverse', { prototype: proto });
    }

    btn.addEventListener("click", function() {
      register();
    }, false);Check out this Pen!
# Using Custom Element * `document.createElement('x-reverse')` * `new XReverse()` # createElement()
var body = document.body,
        btn = document.querySelector("#unreverse"),
        elem = document.createElement('x-reverse');

    elem.textContent = "Palindromes are awesome, level, racecar and best of all tacocat";

    body.insertBefore(elem, btn);

    btn.addEventListener("click", function() {
      elem.unreverse();
    }, false);Check out this Pen!
# Custom Element Recap * Element element * this.register & document.register * Is a real DOM element * Browser support Firefox & Chrome nightlies — unstable. # Shadow DOM * Where the encapsulation happens * Browser vendors have had this * Gives markup and style encapsulation * Enormous amount of info # Shadow DOM
Check out this Pen!
# Preserving content
var btn = document.querySelector(".btn");

    var shadow = btn.createShadowRoot();

    shadow.innerHTML = "<h1>Shadow DOM in the house!</h1><content></content>";Check out this Pen!
# Distributing content
var btn = document.querySelector(".content");

    var shadow = btn.createShadowRoot();


    shadow.innerHTML = "<content select='.hello'></content>, <content select='.world'></content>";Check out this Pen!
# Styling the Shadow DOM * style tag inside Shadow DOM * @host1 soon to be ::host * pseudo attribute1 soon to be ::part() * ::distributed()1 soon to be ::content 1 Note: These are changing # Styling overload
/* User styles through custom pseudo elements */
    .slider::x-superslider-handle {
      color: green;
    }


    /*
     * Easier to read shadow dom styles
     * @host changing to ::host
     */
    @host {
      div {
        position: relative;
        font-size: 10px;
        width: 600px;
      }
    }

    /*
     * ::distributed() changing to ::content
     * content::content img {}
     */
    content::-webkit-distributed(img) {
      max-width: 100%;
      opacity: 0.5;
    }

    h1 {
      font-size: 2rem;
    }
    .slides {
      position: relative;
      white-space: nowrap;
      overflow: hidden;
    }

    .slide {
      display: inline-block;
    }
    .controls div {
      font-size: 50px;
      position: absolute; top: 50%;
      left: 1rem;
      background: rgba(0,0,0,0.5);
      padding: 0.5rem;
      line-height: 1;
      border-radius: 0.5rem;
      cursor: pointer;
    }

    controls div:last-child {
      left: auto;
      right: 1rem;
    }Check out this Pen!
# Recap! * @host: reach outside Shadow DOM * psuedo: reach inside Shadow DOM * ::distributed: style distributed elements * Browser support: Chrome only ATM. # Overwhelmed **A lot** to take in ![](images/overwhelmed.gif) # Templates * Inert chunk of DOM * Not quite native handlebars * Activates on DOM injection # Simple Demo
<template id="trolololo">
      <div class="container">
        <h1>Trolololo</h1>
        <img src="http://stream1.gifsoup.com/view/201665/trololo-o.gif" />
      </div>
    </template>

    <button class="trolololo">Activate LOLs</button>Check out this Pen!
# Templates, Custom Elements & Shadow DOM
<element name="x-reverse">
      <template>
        <style>
          .container {
            padding: 10px;
            border: 1px solid #eee;
          }
          h1 {
            color: red;
          }
        </style>
        <div class="container">
          <h1><content></content></h1>
        </div>
      </template>
      <script>
        if (this !== window) {
          var tpl = this.querySelector('template');
          this.register({
             prototype: {
               readyCallback: function() {
                  this.createShadowRoot().appendChild(tpl.content.cloneNode(true));
                  this.textContent = this.textContent.split('').reverse().join('');
               }
             }
           });
         }
      </script>
    </element>

    <x-reverse>
      I put my thing down, flip it and reverse it.
    </x-reverse>Check out this Pen!
# Imports * How a component is included in the document * Checkout slide deck source code # Performance * That's a lot of http requests you got there * Performance is a key agenda * Multiple elements can be defined * Build process * Defer loading # Extend the Web Forward * Low level APIs * Developers can experiment without standards body slowness * Libraries can be built around low level APIs * [The Manifesto](http://extensiblewebmanifesto.org/) # RWD picture element * RWD and retina displays require different images * picture element proposal * end up with srcset, lolwat? # <x-picture />
<x-picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
      <pic-src src="https://raw.github.com/ryanseddon/picture-component/master/example/imgs/small.jpg"  media="(min-width: 200px)"></pic-src>
      <pic-src src="https://raw.github.com/ryanseddon/picture-component/master/example/imgs/medium.jpg" media="(min-width: 400px)"></pic-src>
      <pic-src src="https://raw.github.com/ryanseddon/picture-component/master/example/imgs/large.jpg"  media="(min-width: 800px)"></pic-src>
    </x-picture>Check out this Pen!
[Github repo](https://github.com/ryanseddon/picture-component/)
# [Polymer](http://polymer-project.org/) ## Handy polyfills + extra layer on top * Wraps up web components into nice library * Handling events * Model Driven Views (MDV) think Angular.js but native * Much more # [X-Tag](http://www.x-tags.org/) ## Polyfill just for Custom Elements * Great examples * Created registry for custom components # They acknolwedge each other ## Hopefully they work together on a common solution # Thanks * Slides: [ryanseddon.github.io/web-components](http://ryanseddon.github.io/web-components) * Polymer: [polymer-project.org](http://polymer-project.org/) * X-Tag: [x-tags.org](http://www.x-tags.org/) * [Spec](http://www.w3.org/TR/2013/WD-components-intro-20130606/)