Dominating Shadow DOM

Tomomi Imura, @girlie_mac

Dominating
Shadow DOM

Tomomi Imura (@girlie_mac)

cat shadow

CC0

Creating Web UI

Web UI

Bleh!

Divitis

Modular UI

UI components
<core-scaffold>
  <core-header-panel>
    <core-toolbar>Chat Room</core-toolbar>
  </core-header-panel>

  <template repeat="{{m in messages}}">
    <x-chat-list uuid="{{m.uuid}}" text="{{m.text}}"></x-chat-list>
  </template>

  <paper-input on-keyup="{{checkKey}}"></paper-input>
  <paper-fab icon="send"></paper-fab>
</core-scaffold>
		
		

W3C Web Components

  • HTML Imports
  • HTML Templates
  • Custom Elements
  • Shadow DOM

Shadow DOM

Shadow DOM enable markup to:

  • be composed in modular pattern
  • be encapsulated (Private)
  • overlay subtree of nodes

Shadow DOM Browser Supports

with vendor prefix
25*
15*
4.4*
no vendor prefix
35
22

Can I Use?

Shadow DOM in User Agent


<audio src="media/meow.mp3" controls></audio>
			

<input type="date">
			

SoundBible.comb

Custom Elements

<x-chat-list 
  color="moss" avatar="korat" username="Moss-Korat" 
  text="happy moew year to you all"
  timestamp="a minutes ago"></x-chat-list>
		
		

Kitteh Anonymous (Polymer demo)

Dissecting Custom Elements

DOM & Shadow DOM

DOM: Creating a Node

<div id="parent"></div>

var parent = document.querySelector('#parent');
var child = document.createElement('div');
parent.appendChild(child);
		

Shadow DOM: Creating a Node

<div id="host"></div>

var host = document.querySelector('#host');
var shadowroot = host.createShadowRoot();

// To append a child node to the shadow root
var child = document.createElement('div');
shadowroot.appendChild(child);
		

Styling Shadow DOM: CSS Scoping

  1. :host and :host() pseudo-class
  2. :host-context() pseudo-class
  3. ::content pseudo-element
  4. ::shadow pseudo-element
  5. >>> shadow-piercing descendant combinator

CSS Scoping Module Level 1 • http://dev.w3.org/csswg/css-scoping/

:host

<element name="x-chat-list">
  <style>
    :host {
      border-bottom: 1px solid #eee;
      min-height: 72px;
	}
  </style>
  <div class="username"></div>
  <div class="text"></div>
  <template>...</template>
</element>

:host()

<element name="x-chat-list" class="fancy">
  <style>
    :host(.fancy) {
      border-bottom: 3px dashed LemonChiffon;
	}
	:host(:hover) {
	  color: DarkSlateBlue;
	}
  </style>
  ...
</element>

:host-context()


:host-context(.fancypants) {
    background-color: LavenderBlush;
}

<div class="fancypants">
  <x-chat-list></x-chat-list>
</div>

::content

<element name="x-chat-list">
  <style>
    ::content span {
      font-weight: 400;
	}
  </style>
  <div class="username"><span>User: </span></div>
  <div class="text"></div>
  <template>...</template>
</element>

::shadow


x-chat-list::shadow > div {
    min-height: 100px;
}

<x-chat-list>
  #shadow-root
  <div>...</div> <-- this is selected
</x-chat-list>

* deprecated in Chrome recently: https://www.chromestatus.com/features/6750456638341120

>>> combinator

Shadow-piercing descendant combinator

x-chat-list >>> div { ... } 

<x-chat-list>
  #shadow-root
  <div> <-- all divs are selected incl. nested divs
    <div>
      <div></div>
    </div>
  </div> 
</x-chat-list>

>>> combinator

audio.fancy >>> input[type=range] { 
  background-color: CornflowerBlue; 
} 
		
Actual DOM: Screenshot:

* Both /deep/ and the combinator are deprecated in Chrome: https://www.chromestatus.com/features/6750456638341120

a black cat and a white cat

https://flic.kr/p/8jP4NJ by Ryusuke b

Thank you <3 <3 <3