Web Components

The old new era


  • HTML is not verbose/"semantic" enough.
  • There is no standard template system.
  • There is no native encapsulation in browsers.
  • There is no way to reuse existing HTML.
  • Everything is a component, right?
  • WE LOVE DECLARATIVE WEB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111111111one

Other/Former approaches

Need for verbosity

  • HTML is semantic only for end user.
  • Developers want to be able to read their code.
  • The era of "developer semantics".

Need for verbosity



The beautifully beautiful slide!


		The beautifully beautiful slide!

Custom elements!

  • Emerging standard for creating our own tags with semantics defined by us.
  • Easy way to extend existing tags.
  • Element's lifecycles.
  • Live detection and enhancement of custom elements.
  • Forced to use special name convention – prefix-name.

New custom element

class XSlider extends HTMLElement {}
window.customElements.define( 'x-slider', XSlider );

Extending existing element

class XButton extends HTMLButtonElement {}
window.customElements.define( 'x-button', XButton, { extends: 'button' } );

Fundamental problems

Native template system

  • All existing template systems are string-based…
  • …but DOM is a tree.
  • How to utilize tree strenghts in templates?
  • How to "switch off" some DOM subtrees (e.g. force them not to fetch images)?


  • template contains inactive DOM subtree.
  • Only inserting its content into some "live" site's element activates this subtree.
  • What's more, template just reuses good old DocumentFragment!

Working with template

const template = document.getElementById('image').content;
const img = template.querySelector( 'img' );

img.src = '/whatever.png';
img.alt = 'Just a placeholder.';

const parsed = document.importNode( template, true );

document.getElementById( 'image-container' ).appendChild( parsed );

Need for encapsulation

  • HTML & CSS are leaky by default.
  • Everything exists in a global scope.
  • Everything is interacting with everything.
  • There is no way to hide implementation details (video tag case).
  • BEM is helping, but it's merely a convention.

Two DOMs

  • Light DOM
  • Shadow DOM

The shadow boundary

  • It hides all implementation details.
  • All styles inside it are scoped.
  • Nothing is exposed to the Light DOM…
  • …so we are forced to create sane API.
  • Light DOM vs Shadow DOM


    Some content



    Some content

    More complicated example


    • Slots are just placeholders.
    • They wait for our content.
    • It has a fancy name: "Nodes Distribution Algorithm".

    HTML as a module

    • We can reuse JS by modularizing it and using script tag.
    • We can reuse CSS by putting it into the separate file.
    • For the very long time the only way to do this with HTML was using an iframe.

    HTML Imports

    Just put your component into separate file:


    And import it from your application's main file:

    HTML Imports and ES Modules

    • They are able to coexist…
    • …but they are two very similar mechanisms, yet totally separate.
    • Will HTML Imports become a subtype of ES Modules?


    • The main goal is to upstream every WC part into DOM and/or HTML standard…
    • …which is already partly done.

    Current browser support

    • Can I Use lies!
    • Only Chrome supports custom elements – but in their former version.
    • Only Chrome supports Shadow DOM – in its former and current versions.
    • Only Chrome is even willing to support HTML Imports…
    • Still in flux – after 3 years.
    • Better go React then!
    • Polymer? Nope!

    Common pitfalls

    • Not everything is a component…
    • …at least not a declarative one!
    • Non-UI related logic inside custom tags? Bah!

    2 pillars of architecture

    • Totally independent UI, created with the use of web components.
    • Business/application/non-UI logic, created with… PURE JS™.
    • Events as the way to communicate between these two separate worlds.
    • Just like in Zakas's idea.

    That's it, guys!