5 ms·
Frankly, web components aren't great. I am using them, because I've landed in a few projects where adding a JS build step is too heavyweight for very minimal J
by kerkeslager 3y ago
Frankly, web components aren't great.
I am using them, because I've landed in a few projects where adding a JS build step is too heavyweight for very minimal JS needs. But here are my gripes:
1. Templates are way too complicated to be useful. I have no idea what they were thinking here.
2. The shadow DOM not inheriting styles means I effectively can't use the shadow DOM for anything useful. My ideal use case would be that I could child elements to the current component into the shadow DOM. This allows me to do (for example) things like have a <tab-area> where the user can define <tab-> child elements which in turn can contain arbitrary content: when the user selects a tab I copy the contents of the <tab-> tag into the shadow DOM so that that's what becomes visible. But if I do that, the element content becomes unstyled. There are a bunch of really useful elements that are just completely blocked by this poor design choice. As a result, I just don't use the shadow DOM, but then I have to mutate the tabs to make them visible in place, and that means changes to the HTML of tabs can potentially cause issues for my <tab-area> and vice versa.
The first is a missed opportunity, but it's fairly easy to just not use them. The second problem is one of the worst API decisions I've ever seen, which would have been detected very quickly if anyone designing this API had been arsed to try to use their own API.
- jacob019 3y agoThe shadow DOM can inherit styles if you specify the styles that you want to inherit. Additionally, web components work just fine without the shadow DOM, it's optional, but for a great many custom elements you don't want them inheriting all the styles, because that can break the custom element.
- vanake 3y agoprobably what GP meant there is now way to inherit styles without specifing which styles you want to inherit. There should option shadow dom inherit all styles.
- webstrand 3y agoWithout the shadow dom, though, what really is the difference from just using `<div>` elements? You can't use slots, you're vulnerable to bad `querySelector`s, events aren't isolated, and you get none of the performance benefits. I've tried to find a workable solution using style inheritance, but it doesn't work everywhere. On code sandbox sites like codepen.io, the stylesheet is generated for you and sometimes updated in-place. You'd have to watch with a MutationObserver and then propagate the change to every instance of a custom element on the page.
- kerkeslager 3y ago> You'd have to watch with a MutationObserver and then propagate the change to every instance of a custom element on the page. This solution works in that you can create a mixin that does this and use it in your custom elements. But if you profile it I think you'll discover it's painfully slow. It's not noticeable if you're using a few custom elements here and there, but if you're, for example, making a table of custom elements, the page will load slowly.
- webstrand 3y agoYeah, that's exactly my experience. I built a framework for quickly prototyping with web components before I discovered the CSS-isolation defect. Sadly it's pretty much killed that idea as unworkable. <https://codepen.io/webstrand/pen/jOzYVpL https://codepen.io/webstrand/pen/jOzYVpL> is as far as I got. The FOUS is pretty annoying, too, before the templates get properly registered. But I could live with that.
- azangru 3y ago> Without the shadow dom, though, what really is the difference from just using `<div>` elements? Having a lifecycle that you can hook into to know when to run code related to this particular instance of the custom element. See e.g. a recent talk on web components — https://youtu.be/jBJ7eoPtmY8?t=367 https://youtu.be/jBJ7eoPtmY8?t=367
- kerkeslager 3y ago> The shadow DOM can inherit styles if you specify the styles that you want to inherit. Ah yes, I've heard about this "mixing CSS into your HTML". The entire point of CSS is that you can write selectors that can affect anything, import it in the header, and you're done. If you're telling me I have to import a new CSS file (or repeat myself and import the same CSS file) inside of every custom element I create, obviously I thought of that. I'm telling you that's a terrible, awful idea, because it breaks the fundamental way CSS is supposed to work. Consider: if I'm distributing a library of web components, which of my users' CSS files that I know nothing about do I include? Did you read the example I already gave? The solution you're offering doesn't solve the problem I've described. > Additionally, web components work just fine without the shadow DOM, it's optional, You should read the post you're responding to in order to find out why that also causes problems. > but for a great many custom elements you don't want them inheriting all the styles, because that can break the custom element. ...just like all of the rest of CSS. We have strategies for dealing with that. The only strategy you've suggested for doing the opposite is a completely useless non-solution.
- azangru 3y ago> Consider: if I'm distributing a library of web components, which of my users' CSS files that I know nothing about do I include? If you are distributing a library of web components, wouldn't you provide a CSS api for the things that are supposed to be styleable via CSS custom properties and styleable parts? Case in point: consider Shoelace. > a completely useless non-solution Consider the existing libraries of web components — Shoelace for something generic, RedHat's Patternfly or Adobe's Spectrum for something company-specific. How much of a non-solution are they, really?
- kerkeslager 3y ago> If you are distributing a library of web components, wouldn't you provide a CSS api for the things that are supposed to be styleable via CSS custom properties and styleable parts? If you read my previous comments you'll see that the parts that should be styleable--i.e. the content of the component I've defined--are user-defined, so no, I can't document them. > Consider the existing libraries of web components — Shoelace for something generic, RedHat's Patternfly or Adobe's Spectrum for something company-specific. How much of a non-solution are they, really? If you read what I said in context, I'm not saying components are useless, I'm saying the unstyled shadow DOM is a completely useless non-solution to the problem I've described.
- LorenzA 3y agoit sounds like the thing you are looking for are slots and they are supported in shadow DOM with the HTMLSlotElement
- kerkeslager 3y agoNo, because then the user of the custom element has to put slot attributes on the things they put in the tabs. Consider this: <tab-area> <tab- text='First'> ...arbitrary HTML that should work intuitively, i.e. be styled like the rest of the document. </tab-> <tab- text='Second'> Note the lack of slot attributes on these tab elements. That's because we want this to behave like normal HTML where you can nest without having to worry about how tab-area was implemented. Why should we have to care that tab-area was implemented with templates/slots? </tab-> <tab- text='Third'> There could be any number of these tabs so you can't put them into slots without some sort of late-generating the slots anyway. </tab-> </tab-area> We want this to render like a group of tabs where "First" and its body are visible, and tabs are peeking up from behind with the texts "Second" and "Third" but the content of those tabs isn't shown until you click the tab (at which point the content of "First" is hidden). That's not achievable with slots. In general, I haven't found a case where templates/slots are actually useful--it's a lot of work to create a bad interface.
- LorenzA 3y agoMost of the time you have the tab and the panel to display the content of the tab a super simple demo implementation of something like this https://web.dev/components-howto-tabs/ https://web.dev/components-howto-tabs/ In regards of slots, they are a nice way to allow a user of you webcomponent to overwrite/replace parts of your component with something else. This is most of the time a more advanced feature and I find it quite nice to build headless components
- kerkeslager 3y ago> Most of the time you have the tab and the panel to display the content of the tab a super simple demo implementation of something like this https://web.dev/components-howto-tabs/ https://web.dev/components-howto-tabs/ That's exactly what I'm saying is bad. Why does the user of the howto-tabs have to type "slot='panel'" when that information is already communicated by the fact that it's a "howto-panel" inside a "howto-tabs"? This is a useless leaking of implementation details. And that page just keeps going and going. Sure, some of that is because they're implementing a few neat features, but most of it is because slots are way overcomplicated for something that's actually easier to do without them.