Demystifying the Shadow DOM
thetshaped.dev
thetshaped.dev
To the point that even the people working on Web Components finally admitted that in 2022: https://w3c.github.io/webcomponents-cg/2022.html
--- start quote ---
It's worth noting that many of these pain points are directly related to Shadow DOM's encapsulation. While there are many benefits to some types of widely shared components to strong encapsulation, the friction of strong encapsulation has prevented most developers from adopting Shadow DOM, to the point of there being alternate proposals for style scoping that don't use Shadow DOM. We urge browser vendors to recognize these barriers and work to make Shadow DOM more usable by more developers.
--- end quote ---
[1]: https://developer.chrome.com/docs/css-ui/declarative-shadow-...
My guess is, most devs just want to use web components with global styles in their page, to make the reusable between frameworks.
However, the moment you want nestable components, you need slots, which are part of the Shadow DOM, which prevents you from using global styles.
You can pass css variables, or full link urls to the stylesheets to the inside of the components. If all your components support that, then effectively you can override any style.
You have two options:
1. you can insert a <link rel=“stylesheet”> tag the same way you might in the <head>
2. Native CSS modules
Example 1: https://developer.chrome.com/docs/css-ui/declarative-shadow-...
Example 2: https://web.dev/articles/css-module-scripts
Another way to style elements that are inside the Shadow DOM (from the outside) is to use the `::part(partname)` pseudo-selector, but you need to set the `part="partname"` attribute on elements inside the shadow DOM in order to allow them to be styled from outside with the pseudo-selector.
Another approach I found which is useful when building components which work with slotted template tags is to project the slotted template's content into another slotted element (e.g. a div) provided by the user the from outside. The second slotted element acts as a viewport which holds the component's rendered HTML output. So the component requires the user to provide both a <template slot="item"></template> element and also a <div slot="viewport"></div> element to project the rendered output into. I wrote a post about it:
https://dev.to/jondubois/web-components-the-template-viewpor...
Part of the problem with web components is that the component can only style the slotted element and not its descendants. There’s all kinds of weird edge cases that make styling web components painful.
What web developers were asking for was scoped CSS and HTML templates. How it became what it is today I don’t know, but it’s been massively overcomplicated while at the same time having really awkward limitations.
There is a simple polyfill however in the meantime which means you can actually use it today. https://github.com/guybedford/es-module-shims
It shouldn’t be a shock that people might feel very differently about those two organisations based on their previous actions and all.
When 1/3 rendering engines implement something, that engine is ahead. When 2/3 engines implement something, the other engine is behind. But you are so keen on dunking on Apple, you’re perceiving 1/3 engines implementing something means that just one of the other two engines is behind. That’s an incredibly lopsided way of viewing things.
I don’t know why it is but almost every time I see your username pop up on HN it’s always bending over backwards to protect Apple from some perceived criticism. People are allowed to talk shit about them, they are going to be ok I promise.
So, I could include Tailwind in all my components and simply use the classes as I do without components?
I am no longer very exposed to the frontend landscape but I am curious if those who gained intimate knowledge of those technologies back when it was all that was present might have a niche lucrative role in the future of web tech. I know they are quick to learn, but the idiosyncrasies were always an arcane art.
On one side it’s understandable that people work more on abstractions and are more productive (e.g. learn React first, then maybe understand how P is different from DIV), on the other side it’s incredibly frustrating to see links that aren’t real links even on Google’s websites.
Well, that's one way to define "productive". If a site contains links that are "clickable divs" or has layout shifts, or whatever other "modern" atrocity, can the work really be rated as "done"?
Without done work, productivity is either zero, or undefined.
Backend dev that dabbles in front end here. What’s the problem with this?
* It's not in the focus order so you can't keyboard navigate to it. You have to add tabindex="0" to the div to correct that. * It's not keyboard operable. You have to add not just a click listener but also a key press event listener and check that the key pressed is Enter. * It has no role so a screen reader user doesn't know that it's a link. You have to add role="link" to it.
It's also missing useful user experience features of actual links
* You can hover a cursor over a real link to see the destination URL in the status bar. * You can copy a real link's URL. * You can use alternate clicks or a contextual menu to open a link destination in a new window.
Search engines can't find and index the destination of fake links.
The other comment explains pretty well what that causes in the browser.
There isn’t much understanding of the architecture of the web these days.
People commonly think of web development as a combination of two things: a browser environment in which their JavaScript application runs, and a backend that can provide an API for it to use.
HTML is seen as something that is constructed by JavaScript in the browser. HTTP is just the way you get JSON from the API. URLs are unimportant beyond the desire to make what appears in the browser’s location bar look nice. There’s little understanding of how hypertext is supposed to work.
Tailwind is popular for CSS. People construct their layouts and styles by adding numerous very finely-grained classes to every element in a way that resembles inline styles. There’s very little understanding of how to organise CSS – the most common argument I hear for Tailwind is that it’s impossible to keep CSS organised without it, as if the alternative is to just write one big stylesheet with everything in a mess. “Coming up with names for classes is hard” is something I’ve heard loads.
Graceful degradation / progressive enhancement is now niche. Unobtrusive JavaScript is pretty dead. Fortunately, server-side rendering is making a comeback, but unfortunately most of it relies upon running front-end things on the server with JavaScript as a speedup to bootstrapping the JavaScript running in the browser.
Front-end code is now written in the context of front-end JavaScript frameworks instead of what the browser natively provides. Browsers natively support web components these days, but they were devised by architecture astronauts and are not pleasant or easy to use. Instead people write components with React, Vue, Lit, etc., which have varying degrees of interoperability with web components, which very few people care about. If you want to use a third-party component, you look for one that is written specifically for your framework.
The web platform itself has come a long way though. Browsers almost completely agree on how to render things; CSS layouts are a lot easier and more capable; you don’t need CSS hacks to target workarounds for specific browsers any more; people upgrade their browsers frequently; and even when there are backwards compatibility issues, there are a lot of tools that will transcode it to more compatible older code at build time or polyfill at run time.
If you’re an old-school web developer, you’d probably enjoy writing code with all of the new options available to you. But you’ll probably be quite frustrated when working with newer developers who view the web more like a deployment target for an executable than a real platform with unique strengths.
Was there ever? It seems everyone thinks they have the best way to organize CSS. But it's always just a system that makes sense to them and only them. I'm not convinced there's some enlightened way to organize CSS
I'm not sure how it compares to the backend world, but here everybody is fighting to hire the top 10%, while the lower tiers keep applying to many positions to get hired eventually.
Obviously throwaway acc to not break any hearts.
The 'shadow' DOM is a 'hidden' space? But it is displayed to the user!
And what about this?
> Use case and examples: 2. The <video> HTML element where there’re default controls exposed by the browser. We see just a video element in the DOM, but it contains buttons and some other stuff inside its Shadow DOM.
Why do we use Shadow DOM for this? It sounds like something HTML and CSS can do just fine.
Shadow DOM is how browser vendors implemented that. They could’ve also said “this is internal magic” but instead they made it a standard so other people can use it too.
Why does everyone need a full operating-system tier browser to render any website with javascript?
Async/Promises/Awaitables -> Callback Hell.
Shadow DOM -> Not being able to defer DOM changes.
For instance, I used to be able to style archive.org old site and implement a dark mode, but then they had the brilliant idea of starting to use shadow DOM and for some reason extensions like stylus/dark reader simply don't work on shadow DOM yet, you can't change those elements, so dark mode does't work. And all for what? The funny part is that the old site front-end was just okay, no problem, it just worked.
Honestly, I just don't get why web developers – especially the ones in internet archive foundation, which really should focus on things such as accessibility – keep changing things that simply didn't need to be change.
It's on the search archive collections. All that "collection-browser" tag is inside a shadow-root. It didn't used to be like that.
[1] https://github.com/chromium/chromium/blob/f02ca734bf0/third_...
[2] https://html.spec.whatwg.org/multipage/document-lifecycle.ht...
Even though there is CSS encapsulation, styles can still leak (cascade?) from the parent element into the Shadow DOM. You therefore need to put a style tag on the root that resets all styles.
Even then, there are some things like CSS transformations that will still affect elements within a Shadow DOM.
Another weirdness is that React modals are usually going to break unless you pass them a reference to the Shadow Root. Most popular libraries have been modified to take such a reference.
They cascade into the ShadowDOM without any issues.
- <my-component class="dark"
- :host(.dark) to style inside the component