← Back to context

Comment by spankalee

17 hours ago

I'm a big web components guy, but calling these web components is a massive stretch of the word component.

The word "component" has to mean something ultimately, and to me the defining feature of a web component is that it's self-contained: it brings along its own dependencies, whether that's JavaScript, templates, CSS, etc. Web components shouldn't require an external framework or external CSS (except for customization by the user) - those things should be implementation details depended on directly by the component.

This here is just CSS using tag names for selectors. The element is doing nothing on its own.

Which is fine! It's just not web components.

edit: Also, don't do this:

    <link-button>
      <a href="">Learn more</a>
    </link-button>

That just adds HTML bloat to the page, something people with a singular focus on eliminating JavaScript often forget to worry about. Too many HTML elements can slow the page to a crawl.

Use classes:

    <a class="button" href="">Learn more</a>

They're meant for this, lighter weight, and highly optimized.

> To many HTML elements can slow the page to a crawl.

You can read the entirety of War and Peace in a single HTML file: https://standardebooks.org/ebooks/leo-tolstoy/war-and-peace/...

A marketing page, SaaS app landing, etc., will not even begin to approach that size, whether or not you add an extra wrapper around your <a>s.

  • Almost 15,000 elements! I do agree that too many elements can slow a page but from my experience that starts to happen a few hundred thousand elements, at least that's what we'd run into making data visualizations for network topologies (often millions of nodes + edges) but the trick for that was to just render in canvas.

  • This is true, yet I've seen plenty of poorly built webapps that manage to run slowly even on a top tier development machine. Never mind what all the regular users will get in that case.

  • This is a wonderful example how people live in the inverse-world.

    Marketing is in the end a way of trying to get people to listen, even if you have nothing substantial to say (or if you have something to say, potentially multiply the effect of that message). That means you have to invent a lot of packaging and fluff surrounding the thing you want to sell to change peoples impression independent of the actual substance they will encounter.

    This to me is entirely backwards. If you want people to listen focus on your content, then make sure it is presented in a way that serves that content. And if we are talking about text, that is really, really small in terms of data and people will be happy if they can access it quickly and without 10 popups in their face.

    Not that I accuse any person in this thread of towing that line, but the web as of today seems to be 99% of unneeded crap, with a tiny sprinkle of irrelevant content.

    • The experience also depends on the desired outcome, and who's outcome that is. The marketers? or the readers? Which comes first? How far should it go?

  • Thank you for this example. I'm going to keep it in mind the next time I asked myself if there are too many elements or not.

HTML elements can style themselves now using the @scope rule. (It's Baseline Newly Available.) Unlike the "style" attribute, @scope blocks can include @media and other @ rules. You can't get more self-contained than this.

    <swim-lane>
        <style>
            @scope {
                background: pink;
                b {
                    background: lightblue
                }
                @media (max-width: 650px) {
                    /* Mobile responsive styles */
                }
            }
        </style>
        something <b>cool</b>
    </swim-lane>

You can also extract them to a CSS file, instead.

    @scope (swim-lane) { /* ... */ }

The reason approaches like this continue to draw crowds is that Web Components™ as a term is a confluence of the Custom Elements JS API and Shadow DOM.

Shadow DOM is awful. Nobody should be using it for anything, ever. (It's required for putting child-element "slots" in custom elements, and so nobody should use those, either.) Shadow DOM is like an iframe in your page; styles can't escape the shadow root and they can't get into the shadow root, either. IDs are scoped in shadow roots, too, so the aria-labelledby attribute can't get in or out, either.

@scope is the right abstraction: parent styles can cascade in, but the component's styles won't escape the element, giving you all of the (limited) performance advantages of Shadow DOM with none of the drawbacks.

  • Decoupling slots from shadow dom would make custom elements even better.

    I love custom elements. For non React.js apps I use them to create islands of reactivity. With Vue each custom element becomes a mini app, and can be easily lazy loaded for example. Due to how Vue 3 works, it’s even easy to share state & routing between them when required.

    They should really move the most worthwhile features of shadow dom into custom elements: slots and the template shadow-roots, and associated forms are actually nice.

    It’s all the extra stuff, like styling issues, that make it a pain in the behind

    • There's really no way to decouple slots for shadow roots.

      For slots to work you need a container for the slots that the slotted elements do not belong to, and whose slots are separated from other slot containers. Otherwise you can't make an unambiguous relationship between element and slot. This is why a shadow root is a separate tree.

      1 reply →

  • That's styling itself sure, but it's not self-evidently self-contained. Does every component emit those styles? Are they in the page stylesheet? How do they get loaded?

    Counterpoint: Shadow DOM is great. People should be using it more. It's the only DOM primitive that allows for interoperable composition. Without it you're at the mercy of frameworks for being able to compose container components out of internal structure and external children.

    • https://2025.stateofhtml.com/en-US/features/web_components/

      Sort by negative sentiment; Shadow DOM is at the top of the list, the most hated feature in Web Components. You can read the comments, too, and they're almost all negative, and 100% correct.

      "Accessibility nightmare"

      "always hard to comprehend, and it doesn't get easier with time"

      "most components don't need it"

      "The big issue is you need some better way to some better way to incorporate styling from outside the shadow dom"

      > It's the only DOM primitive that allows for interoperable composition.

      There is no DOM primitive that allows for interoperable composition with fine-grained reactivity. Your framework offers fine-grained reactivity (Virtual DOM for React/Preact, signals for Angular, runes for Svelte, etc.) and any component that contains another component has to coordinate with it.

      As a result, you can only mix-and-match container components between frameworks with different reactivity workflows by giving up on fine-grained reactivity, blowing away the internals when you cross boundaries between frameworks. (And Shadow DOM makes it harder, not easier, to coordinate workflows between frameworks.)

      Shadow DOM sucks at the only thing it's supposed to be for. Please, listen to the wisdom of the crowd here.

      4 replies →

    • Yeah but most people don't need or want 'interoperable composition', they want sites with a consistent look-and-feel. Shadow DOM makes this much more difficult.

      1 reply →

There's a lot of contradictions in this comment.

> it's self-contained: it brings along its own dependencies, whether that's JavaScript, templates, CSS

> Also, don't do this [...] That just adds HTML bloat to the page, something people with a singular focus on eliminating JavaScript often forget to worry about. To many HTML elements can slow the page to a crawl.

A static JS-less page can handle a lot of HTML elements - "HTML bloat" isn't really a thing unless those HTML elements come with performance-impacting behaviour. Which "self-contained" web-components "bringing along their own dependencies" absolutely will.

> shouldn't require an external framework

If you're "bringing along your own dependencies" & you don't have any external framework to manage those dependencies, you're effectively loading each component instance as a kind of "statically linked" entity, whereby those links are in-memory. That's going to bloat your page enormously in all but the simplest of applications.

It’s funny you say it adds html bloat yet people go crazy for tailwind which is mega bloat!

I might toss it out there that upcoming changes to attr() [0] as well as typed properties [1] will add some interesting features. Being able to provide a value that's subbed into a stylesheet from the HTML itself is neat.

You can try to get by with auto-generated selectors for every possible value today, ([background="#FFFFFF"]{background: #FFFFFF}[background="#FFFFFE"]{background: #FFFFFE}...) but just mapping attributes to styles 1:1 does begin to feel like a very lightweight component.

(Note... I'm not convinced this is a great idea... but it could be interesting to mess around with.)

[0] https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/V...

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/A...

I disagree on the number of elements actually approaching problematic territory, but agree this just isn’t something you can’t do already without web components

According to the dictionary, the word component means "a part or element of a larger whole" which I think goes to the opposite direction of "self contained"