Web Components API – this is for real!

A presentation at Bilbostack 2019 in January 2019 in Bilbao, Biscay, Spain by Belén Albeza

Slide 1

Slide 1

Web Components API (this is for real!)

Belén Albeza @ladybenko

Slide 2

Slide 2

A tale as old as time

From documents to apps

Slide 3

Slide 3

This is a web I made in 1999, in my early teens. I opened it with the latest Firefox version and it looks the same it looked back in the day. We see this as normal, but I cannot say the same about other software I developed only a few years ago – some of my games and mobile apps can no longer be used with modern devices.

Slide 4

Slide 4

Now it’s 2019. I’m working in the Firefox DevTools team, making developer tools for Firefox using HTML, CSS, and JS – the same stack I’ve been using all this time!

Slide 5

Slide 5

It’s 2019 We can’t style a dropdown 💃, nor we do have a <carrousel>, or <toolbar> tags… but we have games, VR experiences, multimedia players, etc. that are built on HTML, CSS and JS.

Slide 6

Slide 6

A common need

Reusable UI widgets

Slide 7

Slide 7

What JS frameworks do

<User username="desatranques">

=>

<span class="user">
  <img class="user__avatar"
   src="desatranques.png">
   Desatranques Jaén
</span>

Slide 8

Slide 8

Web Components API

  • A standardised API to make re-usable UI components
  • Web Components API = Custom Elements + Shadow DOM + <template> + <slot>
  • Since it’s implemented by the browser, it can do things frameworks can’t 😱

Slide 9

Slide 9

API support in browsers

Slide 10

Slide 10

Custom Elements

  • Our own HTML tags! 🎉
  • We can extend from HTMLElement or other subclass
  • https://developer.mozilla.org/en-US/docs/Web/ Web_Components/Using_custom_elements

Slide 11

Slide 11

customElements.define(
  'x-user',
  class extends HTMLElement {
    constructor() {
      super();
      // ...
    }
  }
);

=>

<x-user>

Slide 12

Slide 12

Shadow DOM

  • The DOM is the tree that represents HTML nodes in our document
  • The Shadow DOM is a fragment of the DOM that is isolated from the “light DOM”
  • https://developer.mozilla.org/en-US/docs/Web/ Web_Components/Using_shadow_DOM

Slide 13

Slide 13

Shadow DOM is not new…

Slide 14

Slide 14

JS framework vs Web Component

JS framework:

<span class="user">
  <img class="user__avatar"
   src="desatranques.png">
  Desatranques Jaén
</span>

Web Components:

<x-user>
  #shadow-root
    <span class="user">
      <img class="user__avatar"
       src="desatranques.png">
      Desatranques Jaén
    </span>
</x-user>

Slide 15

Slide 15

customElements.define(
  'x-user',
  class extends HTMLElement {
    constructor() {
      super();

      this.attachShadow({ mode: 'open' });
      this.shadowRoot.innerHTML =
        '<span class="user">...</span>';
    }
  }
);

Slide 16

Slide 16

DevTools + Web Components

  • You can inspect, manipulate, change CSS rules, etc. of Custom Elements with a Shadow root like if they were regular HTML elements!

Slide 17

Slide 17

Demo: A simple component

https://belen-albeza.github.io/webcomponents-examples/wc-simple.html

Slide 18

Slide 18

<template>

  • A tag to aid into creating new DOM with JavaScript
  • It isn’t rendered by the browser, but:
    • We can inspect it with DevTools
    • We can easily clone it and then do an appendChild

Slide 19

Slide 19

<template id="user-tpl">
  <style>
    .user { border: 1px solid black; }
  </style>
  <span class="user">
    <img src="avatar.png">Anonymous
  </span>
</template>

Slide 20

Slide 20

const template = document.querySelector('#user-tpl'); 

this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(
  template.content.cloneNode(true));

Slide 21

Slide 21

Demo <template>

https://belen-albeza.github.io/webcomponents-examples/wc-template.html

Slide 22

Slide 22

Shadow DOM encapsulation

  • JavaScript
    • Some isolation. Ex: document.querySelector won’t go inside, but Shadow DOM can access light DOM
  • CSS
    • No classname collisions, only inherited properties go through
    • Styles don’t leak outside

Slide 23

Slide 23

<slot>

  • Allows the user of a component to inject DOM inside.
  • Multiple slots are allowed for a component
  • Ej:
<x-message level=“success”> <p>Once upon a time…</p> </x-message>

Slide 24

Slide 24

Demo <slot>

https://belen-albeza.github.io/webcomponents-examples/wc-slots.html

Slide 25

Slide 25

Custom attributes

  • We can make up our own attributes and render the content of the component depending on them
  • But we have to listen for attribute changes if we want the component to reflect those changes.

Slide 26

Slide 26

// which attributes to watch
static get observedAttributes() {
  return ['username'];
}

// callback for changes
attributeChangedCallback(attr, oldValue, value) { 
  // re-render component here
  // …
}

Slide 27

Slide 27

Demo: custom attributes

https://belen-albeza.github.io/webcomponents-examples/wc-attrs.html

Slide 28

Slide 28

What about CSS?

  • You don’t need a system to avoid class collisions from the outside (no BEM, or CSS Modules, or CSS in JS…)
  • …or from the inside out! STYLES DON’T LEAK
  • Properties & variables that are inherited permeate to the Shadow DOM (color, font…)

Slide 29

Slide 29

Demo CSS

https://belen-albeza.github.io/webcomponents-examples/wc-styles.html

Slide 30

Slide 30

Recap: pros of Web Components

  • Encapsulation
  • They are HTML Elements
  • Same API’s you know and love: querySelector, innerHTML, appendChild, addEventListener…
  • You can use regular DevTools to debug them • A standardised API

Slide 31

Slide 31

So… can I ditch React? 🤔

Slide 32

Slide 32

No.

Slide 33

Slide 33

JS Frameworks have many features

  • Reusable components
  • Template system
  • Data-binding
  • Other: routers, architecture (Angular, Redux, Vuex…), optimizations…

Slide 34

Slide 34

So what’s the point?

  • Web Components are here to power up frameworks.
  • …or to allow micro-libraries to exist to make shareable components
  • A standard API means that a WC component created with a framework can be used on a different one –or without any framework at all!

Slide 35

Slide 35

Some JS Frameworks already support Web Components

https://custom-elements-everywhere.com/

Slide 36

Slide 36

Web Components made with Vue

  • Step 1: Code your component as usual
  • Step 2: Build with vue-cli and the --target wc flag

Slide 37

Slide 37

Demo: a Web Component made with Vue

https://belen-albeza.github.io/webcomponents-examples/wc-vue.html

Slide 38

Slide 38

Demos + repo

https://belen-albeza.github.io/ webcomponents-examples/

Slide 39

Slide 39

Thanks! Questions?

Belén Albeza @ladybenko