Web Components

Are we there yet?

Christian Köberl / github.com/derkoe / @derkoe
Agenda

Web Component Standards:
Custom Elements, Shadow DOM & Co

When to use Web Components

Implementing Web Components

Christian Köberl

All-End Developer

Develops web apps since 1999

Web Component Standards

Custom Elements

Shadow DOM

HTML Templates

HTML Imports

CSS Variables

Custom Elements

<script src="dk-tabs.js"></script>
<dk-tabs>
  <dk-tab title="Tab 1">This is tab one</dk-tab>
  <dk-tab title="Tab 2"><h2>Antoher tab</h2></dk-tab>
</dk-tabs>

Custom Elements

Can I use Custom Elements

Shadow DOM

Chrome Dev Tools showing Shadow DOM

Shadow DOM

Can I use Shadow DOM

HTML Templates

Parse HTML only once

<template id="item-template">
  <div>Whatever content you like</div>
</template>
const templ = document.getElementById('item-template')
for (let i = 0; i < 100; i++) {
  const node = document.importNode(templ.content, true)
  elm.appendChild(node);
}

HTML Templates

Can I use HTML Templates

CSS Variables

Declare a variable

element { /* or use pseudo selector :root */
  --background-color: #3f0;
}

Use variable

element {
  background: var(--background-color, #9E9E9E);
}

CSS Variables

Can I use HTML Imports

Polyfills / Shims

@webcomponents/webcomponentsjs

Full suport for Custom Elements, Shadow DOM and Templates,
~100kB minified, 31kB zipped

document-register-element

Only Custom Elements (used by @angular/elements),
~14kB minified, 6kB zipped

When to use Web Components

Reusable Web Thingies

Former jQuery Plugins

Examples: gallery, date-picker

https://silverlinkz.net/projects/gallery

UI Frameworks

Ionic Framework 4

Your in-house component framework

App Navigation

Application navigation Google Application navigation Carlog

Your whole app

Screenshot of easy car configurator in Cupra site

Implementing
Web Components

Options

  1. Native API (Custom Elements / Shadow DOM)
  2. Lib / Compiler
    Stencil.js, SkateJS, Polymer, LitElement
  3. Framework
    Angular, Vue, Svelte, ...

Native API

Demo

Stencil

@Component({
  tag: 'my-hello',
  styleUrl: 'my-hello.css',
  shadow: true
})
export class HelloComponent {
  @Prop() name = 'world';

  render() {
    return (
      

Hello, {this.name}

); } }

LitElement

@customElement('my-hello')
class HelloComponent extends LitElement {
  @property() name = 'world';

  render() {
    return html`
      
      

Hello, ${this.name}

`; } }
LitElement always uses Shadow DOM

Lib / Compilers

Comparing NPM downloads of Stenicl.js, SkateJS, Polymer and lit-element Source: www.npmtrends.com

Frameworks

Build component in your framework of choice

Tab Component

Demo

Using Web Components

Example: Angular

  1. Add custom elements schema:
    @NgModule({
      // ...
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
  2. Import the component in your module:
    import '@myscope/mycomponent'
  3. Use it in your HTML:
    <my-component [attr]="val"></my-component>

Does Framework X Support this?

Gotcha: Polyfills / ES5 (IE11)

Stencil works OOTB (even in IE11)!

Fiddle with all others 😭

For Custom Elements + Shadow DOM: @webcomponents/webcomponentsjs/webcomponents-bundle.js

For ES5: @webcomponents/custom-elements/src/native-shim.js

Summary

Use web components for shared stuff

Write small components in Stencil, LitElement & Co

More complex:
use the framework of choice

IE11 is hard

Thanks! Questions? 🍻

github.com/derkoe / @derkoe

References, Further Readings