SHadow dom


by Gustavo Medina

@thegoosie


some challenges when...



  • Creating a libraries, frameworks, embed widgets
    • Duplicate IDs
    • Unintentional styling
    • Hiding implementation details


Encapsulation




  • Creates a boundary between your code and its client
  • NOT PRESENT ON THE WEB...
    • except with <iframe>s      :(

Web Components



  • Templates (chunks of inert markup)
  • Decorators (no spec as of 2/3/2014) 
  • Shadow DOM (encapsulation of a DOM subtree)
  • Custom Elements (devs create their own elements)
  • Imports (packaging and delivering all of the above)

      shadow dom: The basics



      • Just a sub-tree of DOM nodes
      • Subtrees can be associated with an element 
        • scoped id's and styles
        • mark up is encapsulated 
        • subtree is rendered instead of the element's child nodes
        • subtree does not appear as a child of the element


      shadow dom is rendered!


      let's create some shadows


      <template id="shadow">
        <div class="shadow-container">
          Hello Shadow World!
        </div>
      </template>
      
      <div id="shadow-host">Hello World!</div>
      
      <script type="text/javascript">
        var shadowHost = document.querySelector('#shadow-host'),
            shadowRoot = shadowHost.createShadowRoot(),
            template = document.querySelector('#shadow');
        shadowRoot.appendChild(template.content.cloneNode(true));
      </script>

      insertion points part 1

      • <content></content> (insertion point)
      • shadow host's content is projected into the insertion point (distributed content)

      <template id="shadow">
        <div class="shadow-container">
          <h2>Hello <content></content>!</h2>
        </div>
      </template>
      
      <div id="shadow-host">World</div>


      INSERTION POINTS PART 1.5: Select

      • Insertion points as a declarative API!!!

      <template id="shadow">
        <div class="shadow-container">
          <h1>
            Hello <content select=".world"></content>
            from <content select=".location"></content>
          </h1>
          <div><content select="span"></content></div>
          <div><content select="*"></content></div>
        </div>
      </template>
      <div id="shadow-host">
        <span class="world">Mundo</span>
        <span class="location">Nueva York</span>
        <span>Bogota</span>
        <span>New Jersey</span>
        <div>this is other stuff</div>
      </div>

      insertion points part 2





      • Nesting Shadow DOMS  with <shadow></shadow>

      Let's style some shadows





      • styles are encapsulated 
      • distributed content keep styles

        CSS SELECTORS

        • :host(.foo) - targets and style the shadow host
        • ^ (hat) and ^^ (cat) - descendant selectors
          • cross shadow dom boundaries!!!!!
          • document.querySelector('foo ^ bar'); 
        • Pseudo Elements
          • ::content
          • <div part="foo-bar"></div>
            • #shadow-host::part(foo-bar) //in the page

        SHADOW DOM style properties

      • shadowRoot.resetStyleInheritance
      • false - default. Keeps inheriting CSS props
      • true - resets props at shadow boundary
      • shadowRoot.applyAuthorStyles
      • true - author styles are applied to Shadow DOM elements (relative to the shadow root)

      • A word on javascript

        JS is NOT encapsulated! Business as usual (except a few cases)

        • can't traverse DOM inside a <content>
        • some events do not cross the shadow DOM boundaries

        INTERESTING PROPS/Methods




        • hostElment.shadowRoot;
        • root.olderShadowRoot; //if you had a <shadow>
        • contentEl.getDistributedNodes();  //<content> 
        • distributedEl.getDestinationInsertionPoints();  //any distributed element 

        Event retargeting


        • retarget to look like event source is host element
          • except events originated in a distributed node
        • some event do not cross the shadow boundary
          • abort, error, select, change, load, reset, resize, scroll, selectstart

        Questions???



        @thegoosie

        https://github.com/gmedina/penumbra

        thanks!

        Into The Shadows

        By Gustavo Medina

        Into The Shadows

        An introduction to the Shadow DOM.

        • 682