Custom Elements (Web Components) ARE HTML.
Frameworks and libraries merely CREATE HTML.
With Web Components, you can write:
<playing-card is="queen-of-hearts"></playing-card>
…and it just works, rendering an SVG card.
See my <playing-card>
Web Component: https://cardmeister.github.io/index.html
It does not matter when you register the <playing-card>
element in JavaScript — the browser handles it.
You can even build Web Components without JavaScript altogether, using:
<template shadowrootmode="open">
...
</template>
With a framework or library, you typically start with something like:
<div class="playing-card" data-card="queen-of-hearts"></div>
…but you still need JavaScript after the DOM is parsed (hello FOUC!) to transform it into the intended SVG card.
Key points
- Web Components = semantic, declarative HTML
- Frameworks/Libraries = “div soup” that needs post-processing
All modern browsers support Web Components today.
Apple (correctly, following the Liskov principle) blocked Customized Built-In Elements as early as 2013 — showing this is not some new fad. In fact, the browser engines have been using these principles (shadow DOM, encapsulation) internally for complex tags like <video>
and <select>
for many years.
US mortal developers only got public APIs in 2018.
If you’re building a public-facing website in 2025, you can safely drop IE11 support.
- IE11 usage is under 0.2% globally
- Essentially gone in Europe, North America, and Australia
- Slightly higher (but still under 0.5%) in parts of Asia due to legacy apps
- Most traffic even there is on modern browsers
(A polyfill is needed for Web Components if you still want to support IE11, but you probably shouldn’t.)