Modern Web Components

samthor

Sam Thorogood

Posted on June 16, 2019

Modern Web Components

I'm the lead on Santa Tracker. Yes, I know it's June right now—pretty much as far from the holidays as you can get. 💼

I want to talk about Web Components. A quick refresher: these are Custom Elements which might use Shadow DOM, allowing elements of your own name that have their own CSS, styling and DOM contained within them:

<div>
  <my-custom-element></my-custom-element>
  <p>Mixed with regular HTML!</p>
</div>
Enter fullscreen mode Exit fullscreen mode

Polymer Away 👋

One of the reasons we're updating Santa's core UI to remove the Polymer Web Component library is because Polymer is sticky. Polymer only really works when all the other elements it interacts with are also Polymer: anything it touches also needs to work the same way.

This isn't extensible and doesn't give us room to move in the future. Sites like WebComponents.org, released at the height of Google's evangelism for Polymer, proclaim #UseThePlatform, but I suspect the majority of elements there are sticky in this same way.

Smooth Elements 😎

One of the main reasons we're rewriting the core UI of Santa Tracker using lit-element is because unlike Polymer, Lit is not sticky. It's just a helper library that can be used interchangeably with any other element on your page. 🤝

So in doing our rewrite of Santa Tracker, we've found that many elements just don't need to inherit from anything aside the built-in HTMLElement class, because they're only simple building blocks. We call these 'vanilla' elements. 🍨

Lit aside, there's a huge variety of small or large Web Component libraries out there that act as helpers. My good IRL friend Trey writes SkateJS, and just searching the #webcomponents tag on dev.to reveals a bunch of candidates too. 🔎

Of course, you probably shouldn't ship several different libraries: that's just sensible, to save bytes and not overly complicate your code. But if you use Lit one day, but rewrite using Skate on another (with a smattering of vanilla too), you can safely have those libraries co-exist during a migration so your site is never unusable. 🤗

An Example 🔥

For completeness, let's show off what an element looks like in Lit:

class SimpleGreeting extends LitElement {
  static get properties() {
    return { name: { type: String } };
  }

  constructor() {
    super();
    this.name = 'World';
  }

  render() {
    return html`<p>Hello, ${this.name}!</p>`;
  }
}
customElements.define('simple-greeting', SimpleGreeting);
Enter fullscreen mode Exit fullscreen mode

Easy, right? SkateJS has a similar, easy, getting started sample. 🛹

Vanilla Example 🍦

And what a simple element might look like without any libraries, using just the platform:

class SantaChoiceElement extends HTMLElement {
  constructor() {
    super();

    const template = Object.assign(document.createElement('template'), {
      innerHTML: `
<style>/* CSS here */</style>
<div class="wrap">
  <!-- more HTML -->
</div>
`,
    });

    // polyfill for CSS in Shadow DOM
    if (self.ShadyCSS) {
      self.ShadyCSS.prepareTemplate(template, 'santa-choice');
    }
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(document.importNode(template.content, true));
  }
}
customElements.define('santa-choice', SantaChoiceElement);
Enter fullscreen mode Exit fullscreen mode

And this code is only as complex as it looks (with the polyfill for Shady CSS) for the ~10% of users who don't support Shadow DOM. Lit is including this "for free". 🆓

As an aside; <santa-choice> is an element I'm really proud of that drives the chooser thing at the bottom of Elf Maker 🧝. I'd like to write how it works some day soon.

Thanks!

I hope this has enlightened you a bit about WCs (Web Components). For me, the absolute insightful moment was when I realised that the benefit of using Lit, or other libraries, was that it was not all-in: they play nicely with any other part of the ecosystem and you can use as little or as much of it as you like. 👍

16 👋

💖 💪 🙅 🚩
samthor
Sam Thorogood

Posted on June 16, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related