Hacker News new | ask | show | jobs
by MrThoughtful 630 days ago
I have been following the web components discussion for years now and just don't see what I can do with them that makes my life as a fullstack developer better.

All the examples I have seen use them to template some data into html. I can do that with handlebars already.

Am I missing someting?

8 comments

There are two models of the "web", where HTML is a document and where HTML is the scenegraph of a more complicated app.

If you're using HTML as a document you can use web-components to include fancier interactive real-time feature

* A terminal emulator web component that attaches to a websocket * A date picker web component, add features like checking if a date is already taken * Custom form elements in general, a search-box that takes a URL for auto-completion suggestions * A map, but not a full mapping application * A data table, like the jquery plugin of old * Lightweight interactivity like tab widgets * Basically any of the custom components that jquery-ui provided

Yes you can do all of these without webcomponents, but the HTML is a lot cleaner and a lot more document like if it's a custom component. Mixing the model and scenegraph views of the web is not my favorite. It sure would be nice if there was a consistent library of web components available.

You can actually do pretty decent live-chat with something like HTMX and server-sent-events, I think. But it's sort of a progressive-enhancement view of HTML as a document model.

Full native isolation. HTML, CSS, JS, the whole thing, no tricks, the browser isolates it for you. It's really nice to be able to make a web component, clearly define the JS, HTML and even CSS API in terms of variables, and then throw it into any environment without it breaking, or without creating a complex maze of CSS name spaces and framework dependencies.
Is there really ever a use case for that?

When do you want part of your page to have different fonts, colors, everything from the rest of the page?

We ran into this too, and ended up not using the Shadow DOM at all. We want our stuff to automatically use the page's fonts, sizes, colors etc. Also we want customers to be able to customize stuff with CSS without having to use JS hacks to inject CSS into the shadow DOM (this gets especially cumbersome when you're nesting web components). Personally I feel like the shadow DOM is the most oversold part of web components, in that it's so all-or-nothing that it often creates more problems than it solves.
Which is another thing I love about web components - if you don’t want shadow dom, then don’t use it - you can build using just custom elements.
True, but i wish there was a way to say "don't inherit anything here except fonts and colors".

Being able to make a new root for rems would be nice too.

The Shadow DOM does exactly what you are asking for here. Just use CSS variables, they pierce right through:

https://open-wc.org/guides/knowledge/styling/styles-piercing...

It is not a choice in many situations. For a large company that has many different teams that own many different parts of a product, even though teams adhere to the same "UI standards", things get complicated quickly. For example, CSS classes that have name conflict can cause UI to break (which happens more often than you think, and strictly adhering to naming rules is just hard for humans). That's just one example. Custom elements with shadow DOM is a simple and straightforward solution to this, and it makes sense -- JavaScript code are scoped to modules and use imports/exports to define interfaces, and it is just natural to do that for UI instead of putting every class that other people don't care about in the global CSS space.
The use-case for having isolated objects with parameters, much like classes in Java, is to be able to a) share code, b) hide internal details, and c) have object behavior be governed solely by a constrained set of inputs.

So the point isn't to have your web component be different from the rest of the page. The point is that you can pass in parameters to make an off-the-shelf component look how you want. However, exactly how much freedom you want to give users is up to the component author. It is possible for there to be too little freedom, true.

See here [1] for a concrete example of someone writing a reusable web component, and figuring out how to let users customize the styling.

[1]: https://nolanlawson.com/2021/01/03/options-for-styling-web-c...

In terms of style isolation, the answer is very much “it depends”. And it depends as much on the nature of what the component does, as the kind of isolation you want to achieve.

- Namespace isolation. Example: you have different components in the same codebase or otherwise meant to work together; you may want assurance that a locally defined style attached to class “foo” doesn’t have unexpected effects on other components which happen to use the same class a different way. This is commonly achieved with build tooling, eg by mangling class names.

- Cascade isolation. Example: you have an embeddable widget that you want to look consistent in any context, regardless of the styles of its parent DOM. This is achievable to some extent without custom elements, but they are a way to achieve it with confidence in a relatively straightforward way (at the expense of other limitations and complexity).

This 100%. Web components get praised for this isolation - and it’s like the exact thing I do not want if I’m building an application. Like try to have a global CSS theme, or use bootstrap, etc. (Please don’t suggest I embed a link to global CSS in every component.)

Like I get it if you’re sharing a component on different sites, like an embedded component or ad banner, etc. But it just gets in the way if you’re trying to do normal things that the majority of web apps need.

There are ways to apply global styles to your components other than importing a global sheet. There's just not a standard way defined in the spec. Isolation by default is the correct path for them to take compared to the alternatives. That doesn't make it useless just because you don't know how to do it in a good way.

See https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...

My main point is that gets in the way, unlike most other web frameworks when building normal applications. It's a headwind that always comes up and hurts adoption imho.
From reading the parent site the use cases seem to be large enterprise and cross site components, say a twitter embed or advertising bar.
Web components don't do any JS isolation, right? And when you say HTML isolation I think its probably important to say that any custom element registered is global, so if Web-Component-A uses Web-Component-B version 1 then Web-Component-C cant use Web-Component-B version 2 (unless Web-Component-B includes the version in its name).

If you want actual isolation of the whole web stack (HTML/CSS/JS) I don't think there are any alternatives to iframes.

It is my personal nightmare. I want to write custom css to customize my Homeassistant. Only to find out every single thing is in a shadow root and I cannot write css to adress what I want to change. WHICH WOULD BE REALLY SIMPLE IF I CAN WRITE PLAIN OLD CSS.

I can't believe how extremely mad and frustraded I became when I found out - writing this out fills me with rage.

They are very good for progressive enhancement, for example you could have a web component that wraps a <table> to add fancy features like filtering or drag-and-drop reordering. If JS is disabled or fails to load, the user just gets a plain table, but they still get the content. When this stuff was new, that was much better for the user than what would happen with a front-end framework (they would get a white page), but now server-side rendering is widely available in those frameworks it’s less of a selling point.

They are also good for style encapsulation, i.e. you could drop someone else’s component in your page and not worry about it affecting or being affected by your CSS. Anecdotally I feel like that is less of a common desire now than it was ~10 years ago, with the rise of both “headless” UI libraries (behaviour without dictating appearance) and the prevalence of scoped styles in front-end frameworks.

What does annoy me about the standard is that to use slots you must opt into the shadow DOM, which means that if you’re trying to create reusable components for your own stuff, you can’t style them just by dropping a stylesheet into the page. I’m sure there’s a technical reason why this is the case, but annoying nonetheless.

Without the shadow dom, your component can still have children.

If you need several slots, there's an example duplicating that functionality with javascript in the second comment of this blog post: https://frontendmasters.com/blog/light-dom-only/

the examples probably avoid talking about the dynamic APIs because they are super ugly and very stateful. It's hard to say that Web Components are the future when your demo shows 200 lines of manual DOM reconciliation.
I‘ve come to the same conclusion while using them pretty extensively. The idea is nice, but they are not there yet.
Sure, there is some pain but after years of several Angular and a Vue migration, I'd say that pain is much less than the pain of framework migration. People often overlook the experience of a framework for a long term use.
This could summarize every interaction I’ve had with Web Components since the beginning. Web Components are becoming the Nuclear Fusion of Web standards.
Only 10 more years or so, pinky promise ;)
Web Components let you use a UI component made in a different framework than yours. That's it. For most other purposes they're pretty awful.

Also they let you publish a UI component that works in every framework, without having to build 7 versions of it (or just exclude everyone who's not on React, or something like that)

That’s also the conclusion I’ve drawn. This seems to be the reason Web Components exists.
IMO the slots that allow a component to have children are the difference. You can compose indepent components that way. Also the styles are scoped to the component by default, and you can only break the scope with custom vars (css vars)
Web components are a standard and built into the browser, Handlebars is a separate library. Web components are a way to encapsulate and isolate structure (html), appearance (css) and behaviour (js) into components, extending HTML.

It's like jquery widgets but without dependencies.

Are you genuinely asking as a professional? Seems like a big ask for someone to go over all you are misunderstanding if you think they are equivalent to a template language.
The standard, like PWA, is designed for maximum feasible misunderstanding. To the average dev it seems like a random bunch of features that don’t hang together. Five developers could look at it and be like the blind men discussing the elephant —- hung up on individual parts and not seeing the whole, if there is a whole.

There are a lot of candidates for “what’s wrong with modern web standards” but this fragmentation, which comes from a rather mathematical view of programming, is one of them. Thing is, a lot of web devs never studied computer science (even CS 101) and less than 5% live in San Francisco.

> and less than 5% live in San Francisco

How will they ever understand web components.

On the other hand, if they're completely different from a template language it seems like it should be just a moments work to demonstrate why, and help a fellow professional understand what they're missing.
Well um

1) You dont have to load an external library

2) Shadow DOM

3) Dynamic slots

That’s about it, honestly LOL.

I guess the main point of most browser APIs was to let apps use browser features.

This one actually tried to make a standard way for apps to use other apps. But they already had their own libraries so nyeh, thank you very much! LOL

Now I'm curious, what template engines don't have dynamic slots? Is that actually a rare enough feature to declare webcomponents special for having it? Does webcomponents have an advanced version of it?