What originally started as a method for providing some elements with browser-specific styling has changed a lot. You can find an example-strewn comparison between V0 and V1, as written by one of the W3C authors, here(1). The official, really dull description of Shadow DOM can be found at W3C(2).
When gathering information on this subject, I noticed that many of the blogs using the V1 specs were using broken demo code. There have been some changes to the specs before finalization that weren’t picked up in time. For example, you can now have at most one shadow DOM per element. Some elements no longer accept shadow DOMs at all: any element that the browser already injects with a shadow DOM, you cannot. The only elements that accept a shadow DOM are article, aside, blockquote, body, div, footer, h1, h2, h3, h4, h5, h6, header, main, nav, p, section and span.
You can check the actual support for Shadow DOM V1 across all available browser on the CanIUse (7) site.
Shadow DOM benefits
- It is an isolated DOM element and cannot be accidentally accessed by using greedy querySelectors.
- The shadow DOM CSS does not affect the rest of the page. So, you can work with simple selectors without running the risk of style name clashes. This makes it ideal for use in components. The component can still reply on styles passed to it from the host if desired.
- Events that happen in the shadow DOM are invisible to the host, unless specifically exposed. They then appear to originate from the element containing the shadow tree instead of the actual element inside the shadow tree.
- Browser support is not universal. Chrome, Firefox, Opera, Safari and the Android browser support shadow DOM V1 for the most part. IE will never have it natively. Edge will support it once it’s running on the Chromium engine.
- You can polyfill shadow DOM support, but it comes with a hefty performance hit: it will perform a lot slower than native support. You can find the polyfill script on webcomponentsJS(4) (along with other interesting implementations of shadow DOM).
How do I actually use this thing?
Using the shadow DOM itself is pretty simple. An example: