There are plenty of great responses already, but to add a perspective I think might benefit folks who don’t especially care about the style and Web Component isolation aspects: Shadow DOM standardized those aspects of encapsulation not just for user-authored stuff, but also for encapsulated behavior of browser-native functionality. So for a very silly example, you can now inspect the shadow DOM of an image that failed to load and see the resulting DOM representation that the browser uses in place of the intended image. You can do the same for form field elements and a lot of other elements which used to be totally opaque.
This is great not just to understand more about what’s happening when browser-specific stuff goes sideways, it’s also a really good place to take design inspiration for encapsulating your own stuff. Besides scoping styles and fully isolating children as implementation details, the native implementations often make judicious use of `part` and `slot` aspects of the relevant/related APIs to handle interop with the non-encapsulated parts of their interface. In a lot of ways this allows elements (both native and custom) to provide much stronger contracts than the mostly tag soup that HTML tends to be by default. And it’s especially great that the interface for this is largely (if not totally now?) how built in behavior works, so writing code that targets the browser has the same privileges and the same limitations as the equivalent code the browser provides.
The isolation was primarily designed with Web Components in mind, but
it's popular as well in browser extensions. Content-scripts might want to inject elements into a host page without being subject to that page's styles or JavaScript. (e.g. the host page calling normalize() on their DOM.)
There was a thing called "scoped css" back in 2012 that never went anywhere which seems similar. But I think Shadow DOM also mixes in some notion of DOM access protection iirc. Also interested in a description of what shadow dom is and what it can be used for.
Indeed, Shadow DOM is a great way to isolate styles when working with browser extensions. In fact I’ve made a tutorial and it shows how CSS is scoped to the extension without interfering with any website style:
https://www.freecodecamp.org/news/chrome-extension-with-parc...
It exists to help you define components without running into naming conflicts. For example, if I want to make a "my-button" component that has a <button class="button"> and some CSS that targets `.button { ... }`, I won't end up styling a bunch of other things that have `class=button`. Pretty sure it also protects against other things doing `document.getElementById("button")` and getting the element whose ID is `button` from your component instead of whatever the caller was expecting. Effectively, shadow DOM provides encapsulation.
That's true, but they didn't ratify yet a standard on how to handle web components naming collision, so if you create `my-button` and another developer register `my-button`... Or if you want to use two different version of your own `my-button`...
The namespaces are URLs, so DNS ensures the domain names are unique globally, the owner of each domain name ensures the paths are unique for that domain, and the author of the XML document ensures the namespace aliases are unique for the specific namespaces used in that specific document.
I’m probably the wrong person to ask, but my mental model is that it scopes/isolated the CSS inside the component so it doesn’t affect elements elsewhere in the document but it also prevents CSS elsewhere in the document from affecting the elements in the component.
My outstanding question here is: how do people reuse components across sites with different themes? Do they have to pass styles across the shadow boundary via JS? Or do they just give up on cross-project reuse or theming?
Shadow DOM isn't a totally sandboxed construct, though it mostly is. You can't load font-face's within shadow dom's. They have to be defined in light dom, and then are available in shadow dom. Most other CSS styling seems to be totally isolated, given this exception.
Surely there is more to it than that. What am I missing?