←back to thread

218 points mdhb | 1 comments | | HN request time: 0.225s | source
Show context
jlukic ◴[] No.44393980[source]
It’s worth noting this was written by maybe the person with the most experience in the space i can think of—-the primary author of Lit / Polymer working at web components on Google and contributing on many core DOM specs that have become part of the web platform.
replies(1): >>44394620 #
troupo ◴[] No.44394620[source]
> It’s worth noting this was written by

by one of the people wrecklessly barging forward with half-baked specs that introduced significantly more problems than they solved, pushed a "solution" that requires 20+ new web specs to barely do all the things user-space is already doing while completely ignoring and gaslighting anyone who wasn't 100% on board with what they were doing.

Safari argued that there should be a declarative ways for this 15 years ago

replies(3): >>44395627 #>>44396018 #>>44402550 #
JimDabell ◴[] No.44395627[source]
Web components were such a big disappointment. 200% the complexity for 20% of the functionality. Everything coming out of that area seems to be hideously over-engineered while failing to solve the problems people wanted them to.

My feeling is that they were focused on designing something that is aimed at building form controls, not the kinds of components web developers use in practice. They are designed to make browser vendors’ lives easier, not web developers. That’s often excused with “web components excel at ‘leaf‘ components” when what is actually meant is “web components are bad at everything else”.

I would expect an actually good solution that fits in with the web’s architecture to come from the direction of HTMX, not web components.

> Safari argued that there should be a declarative ways for this 15 years ago

True, but they were equally able to propose and deploy alternative solutions and mostly just went along with web components (with exceptions of course).

replies(3): >>44395735 #>>44402549 #>>44403481 #
_benton ◴[] No.44402549[source]
Im not sure what you're referring to, they seem pretty straightforward to me. Create a class that extends HTMLElement, implement stuff in connectedCallback and attributeChangedCallback. Return a list of attributes in static observedAttributes. Or use some extended class if you want, there are plenty and they're easy to create your own.
replies(2): >>44403506 #>>44405353 #
JimDabell ◴[] No.44405353[source]
Let’s take this example:

    <!DOCTYPE html>
    <title>Example</title>
    <cool-dog>
        <template shadowrootmode="open">
            <style>
                :host {
                    display: block;
                    font-family: system-ui;
                    margin: auto;
                    width: fit-content;
                }
                ::slotted(img) {
                    border-radius: 1em;
                }
            </style>
            <slot></slot>
        </template>
        <img
            src="https://placedog.net/512/342?random"
            width="512"
            height="342"
            alt="A dog"
        >
        <p>Check out this cool dog!</p>
    </cool-dog>
    <script>
        customElements.define(
            "cool-dog",
            class extends HTMLElement {},
        );
    </script>
First off, what’s with the pointless JavaScript? There’s no need for imperative code here. All web components have a dash in the name; this can be inferred. But even if you want it to be explicit, this could be done with markup not imperative code. But no, it doesn’t work without the pointless JavaScript ritual.

Now, I’ve noticed that since the text is a caption for the image, I should actually use <figure> and <figcaption>. So let’s do that:

    <!DOCTYPE html>
    <title>Example</title>
    <cool-dog>
        <template shadowrootmode="open">
            <style>
                :host {
                    display: block;
                    font-family: system-ui;
                    margin: auto;
                    width: fit-content;
                }
                ::slotted(img) {
                    border-radius: 1em;
                }
            </style>
            <slot></slot>
        </template>
        <figure>
            <img
                src="https://placedog.net/512/342?random"
                width="512"
                height="342"
                alt="A dog"
            >
            <figcaption>Check out this cool dog!</figcaption>
        </figure>
    </cool-dog>
    <script>
        customElements.define(
            "cool-dog",
            class extends HTMLElement {},
        );
    </script>
Wait a sec! The nice round corners on the image have turned into ugly square ones. Why is that?

It’s because web components can’t style anything other than their direct children. You can style the <img> when it’s a direct child of the web component, but as soon as you need anything more complex than an entirely flat hierarchy, you run into problems. Even if it’s something as simple as wrapping an <img> in a <figure> to associate it with a <figcaption>.

What’s the “official” way of getting things like this done when you bring it up with the people working on the specs? Make a custom property to fake the real one and then set a global style that listens to the fake property to set it on the real one:

    <!DOCTYPE html>
    <title>Example</title>
    <style>
        img {
            border-radius: var(--border-radius);
        }
    </style>
    <cool-dog>
        <template shadowrootmode="open">
            <style>
                :host {
                    display: block;
                    font-family: system-ui;
                    margin: auto;
                    width: fit-content;
                    --border-radius: 1em;
                }
            </style>
            <slot></slot>
        </template>
        <figure>
            <img
                src="https://placedog.net/512/342?random"
                width="512"
                height="342"
                alt="A dog"
            >
            <figcaption>Check out this cool dog!</figcaption>
        </figure>
    </cool-dog>
    <script>
        customElements.define(
            "cool-dog",
            class extends HTMLElement {},
        );
    </script>
Now let’s say I want to put a second <cool-dog> element on the page. What does that look like? You define the template once and then just use <cool-dog> a bunch of times? That would be the obvious thing to do, right? Since it’s a template?

Nope. Every instance of the web component needs its own <template>. The best you can do is write some JavaScript to copy the template into each one.

The developer ergonomics of this stuff is terrible. It’s full of weird limitations and footguns.

replies(1): >>44406656 #
throwitaway1123 ◴[] No.44406656[source]
> First off, what’s with the pointless JavaScript? There’s no need for imperative code here.

Exactly, I'm not sure why you've included the JS. The whole point of the Declarative Shadow DOM is to create shadow roots declaratively, rather than imperatively. To quote web.dev "This gives us the benefits of Shadow DOM's encapsulation and slot projection in static HTML. No JavaScript is needed to produce the entire tree, including the Shadow Root." [1]

[1] https://web.dev/articles/declarative-shadow-dom#how_to_build....

replies(1): >>44408429 #
troupo ◴[] No.44408429[source]
> The whole point of the Declarative Shadow DOM is to create shadow roots declaratively, rather than imperatively.

It's a pipe dream that doesn't work in practice. Because on its own declarative shadow dom is useless.

replies(1): >>44408572 #
throwitaway1123 ◴[] No.44408572[source]
You clearly have an axe to grind, and I'm not particularly interested in proselytizing. If you don't find the Declarative Shadow DOM useful, that's fine!

The example I was responding to was using the Declarative Shadow DOM. My comment was intended to point out the simple fact that the imperative component definition the author was complaining about is superfluous, meaning you can safely remove that entire script from the example.

replies(1): >>44413882 #
1. _benton ◴[] No.44413882[source]
I'm so fascinated by the few people online who show up to anything web component related just to flame and complain. It's always the same things too.

DSD is useful for SSRing web components, which allows them to render and work without JS. But honestly, I don't get the obsession with doing stuff without JS, it's part of the html/css/js trifecta.