Tinkering with Web Components

Today I found some free time to try out an idea that I had in mind for quite some time. I tried to refactor a part of this site to a web component. I've ended with mixed feelings.

Although I really dig the idea of reusable custom elements and have read more than one article on the topic, I never actually used or even created a web component yet. It was time to change this. So I started with an open tab on CodePen and an open tab on the "Using custom elements" tutorial on MDN. The plan was to convert this sharing button into a reusable web component that I could easily introduce on my other sites.

As it turned out, building the component itself wasn't that big of a challenge. The chosen part of the site is more or less just an if and an addEventListener(). That's the kind of complexity of JavaScript that I like and normally write. Thanks to the awesome work of the editors at MDN, it was a breeze to convert that code to my very first custom element <msme-sharing-button>.

Then I thought about the styling of the button and that seems to be the hard part here: Since the button is rendered on the shadow DOM the CSS of the surrounding site won't have control over it. I've expected that and that's a good thing as long as I'm operating within a closed system. In my case, the buttons on my sites are quite different in terms of size, spacing, fonts, colors, hover effects, and so on. My first idea was to define a set of CSS custom properties to inject the necessary information. But that set got bigger and more complicated with every minute I thought about it.

Some research brought me to the HTML is attribute, which is a different way to bind a web component to an existing element in order to extend its function. <button is="msme-sharing-button" ... should be the solution! Then I found out that I should have read the documentation of is until the end: Safari does not support the attribute. But Safari is also the only browser on macOS at the moment to support the sharing API that I'm tinkering with. Although there's actually a polyfill for custom elements which seems to be pretty good, here's the dilemma:

  • I have an implementation of my web component that needs a lot of styling information. Check it out: Native Sharing Web Component . I don't feel too good with the idea to put the whole styling into a data attribute on the DOM.
  • And then there's the easier to style solution Native Sharing Web Component with is-Attribute and Polyfill . That's the one that only works in the targeted browser when an additional 2 kB of JavaScript is applied which is in this particular case way too much.

At the moment I tend to use solution number two. The additional payload will be marginal when there are more web components in the sites sooner or later. But I have the feeling that I'm missing something. Maybe the internet can help?

3 Webmentions

  1. Avatar of mariohamannmariohamann replied to this post on twitter:
    1. You could try to import your external styles like described over here: developer.mozilla.org/en-US/docs/Web… 2. You could try to use LightDOM instead of ShadowDOM like e.g. described here: discourse.world/h/2020/02/07/W…
  2. Avatar of Søren BirkemeyerSøren Birkemeyer replied to this post on twitter:
    "an additional 2 kB of JavaScript […] which is […] way too much" 😍
  3. Avatar of Dominik SchwindDominik Schwind reposted this post on twitter.

Other articles I've written recently