Cover image for Web Components — the right way.

Web Components — the right way.

equinusocio profile image Mattia Astorino Updated on ・3 min read

From about two years we have been heard about web components, well this article will not explain how they work (for that there is Google), but rather we will address the purpose of this technology, when and how use it.

We can consider web components as a tool to extend HTML, not to replace it. The available technologies follow the same rules that we are all used to —from always— see in the most famous language markup in the world.

Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilise them in your web apps.

HTML — Accelerated course

Every web developer knows — or at least should — the basics of HTML and how to define the markup of a web element that will be represented by the browser in a certain way and with a specific behaviour.


In the above example, like the greatest part of HTML elements, the node can accept a content that will be shown (and stylised) by the browser or by CSS user. But as we all know, it exists also elements that can not accept children nodes (well known as void elements) —for example the <img> and <input> tags — and other tags that require only some types of nodes.

The <select> element, like more other, is a node that uses a shadow DOM similar logic; for this reason, if you want, you can see the content of these elements in the same way as per web components:


This is approximately the mechanic beyond this language, so we can define two different HTML element models:

  • Modular elements — Allow children nodes (normal elements)
  • Self-closing elements — Does not allow children nodes (void elements)

Custom elements

As we wrote, the technologies beyond web components aim to extend HTML, not to replace it. What does it mean? That we have tools to create new HTML elements that would not naturally exist if not implemented by user-agents (browsers), or to extend the behaviour of those ones already existing by adding functionalities and custom styles.


The answer is easier than you expect. Define new HTML elements is necessary when the available ones do not meet functionality and design needs.

If we need to create a new <my-button> element with a customised style, we must think about the progressive enhancement. So we should add functionalities and styles, rather than completely recreate the element from scratch.

The wrong way

If we surf on the Internet, we can find some pattern libraries fully composed by custom elements (using or not some frameworks, like Polymer), tests, examples, playgrounds …and they all have one thing in common, they are all created using a wrong pattern. Do you remember? We are extending the HTML, so we should follow its paradigms and its composition. Here some examples:

An entire app inside the shadow root. It’s the same as putting the app inside the <input> tag.

A native <button> element wrapped… inside another custom button. It’s the same as putting a <button> inside another <button>.

Does this image really need a description? Think about the <select> example above.

This article continue on...



markdown guide

You make some good points in an ideal world but webcomponents are still missing a key feature that would allow for progressive enhancement. We still can't extend any element other than a standard HTML element which is why we still wrap or replace the stock elements.

Ideally, if you wanted to create a custom select element, you would extend the stock select element to gain it's functionality and then define your own UI. Then, if the user was on a browser that didn't support webcomponents or had JS disabled they would be shown the stock select instead.


They are discussing about how to extend native html elements (Please check the google fundamental link). There is already a living standard spec to extend html elements that is now under reconsideration to improve it. Nothing definitive, but since we are talking about a new technology.. it's acceptable.

About nojs browsers, no PWA will work if you disable js...


Wasn't the 'is' attribute supposed to allow for nojs progressive enhancement? That's what I was thinking of anyway.

  1. A customized built-in element, which is defined with an extends option. These types of custom elements have a local name equal to the value passed in their extends option, and their defined name is used as the value of the is attribute, which therefore must be a valid custom element name.

But this spec is now under reconsideration:

#662 - 509


I actually like the Gold Standard (github.com/webcomponents/gold-stan...) it's kinda describing what you mean, isn't it?

Could you please explain what you mean by the <my-button> example? Isn't that the way to go due to the lack of customized built-ins? Thx in advance


Hi, gold standard is much more related to the technical development, this article talk about something more abstract. But yes, they aim to the same point. Telling to users how to use web components by the HTML approach.

If you can extend, check this section of the google fundamentals doc.
If you can't extend and you are making a custom button element (even if i don't see why you should do that), you should recreate it. Your <my-button> will become the button itself (using accessibility attributes), it should not wrap another <button>. This mean that you should recreate all the native button behaviours (or those you need) and add your new features. This does not mean that you can't put a button inside a shadow-root, just not inside a custom element that aim to replace the button itself.

Do you would put a <button> inside another <button> in the HTML? Why you should do that with custom elements?


Yep, customized built-ins would be ideal. We agree.

What do you think of how elix's AutsizeTextarea does it?

Recreating (as you describe) means building a new element with a (potentially) different behavior set, running the danger to not really behave like an extended element, wouldn't it?

Recreating (as you describe) means building a new element with a (potentially) different behavior set, running the danger to not really behave like an extended element, wouldn't it?

Yes, until we can fully extend built-in elements each ”recreated" custom element should behave the same as the native one.. and that's why is hard to think, hard to do and generally a bad practice. I think it's really hard to find some built-in element that needs to be recreated... about elis'x autosize textarea, they added a funcionality but they can avoid using a <textarea> element and use a content-editable element (recreating the textarea behavior and so on...)


@equinusocio the canonical URL no longer works. Could you please update the blog post here?