Shadow DOM v1 works in Chrome 53+, Edge 79+, Firefox 63+, Opera 40+, Samsung Internet 6.2+, and Safari 10+. Per-browser support, modes, slots, and known issues.

Prince Dewani
May 6, 2026
Shadow DOM v1 is the W3C DOM standard API that attaches an encapsulated DOM subtree to a host element, isolating its markup, styles, and scripts from the page. It works in Chrome 53+, Edge 79+, Firefox 63+, Opera 40+, Samsung Internet 6.2+, and Safari 10+ on macOS, 11+ on iOS, while Internet Explorer never shipped it.
This guide covers what Shadow DOM v1 is, browsers that support it, its key features, v0 vs v1 differences, support checks, and known issues.
Shadow DOM v1 is the second-generation Shadow DOM specification, part of the Web Components family in the W3C and WHATWG DOM Standard. A developer calls element.attachShadow({mode: 'open'}) to attach a sealed DOM tree to a host element. The tree has its own markup and CSS that the outer page cannot reach.
Every major modern browser supports Shadow DOM v1 by default. Internet Explorer is the only one that never did.
Chrome supports Shadow DOM v1 from Chrome 53 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 4 to 52 did not support it. Custom Elements v1, the partner spec for Shadow DOM v1, shipped in Chrome 54.
Microsoft Edge supports Shadow DOM v1 in the Chromium-based Edge from version 79 on. The older EdgeHTML versions (12 to 18) did not support it.
Firefox supports Shadow DOM v1 from Firefox 63 on, on Windows, macOS, Linux, and Android. Firefox 58 to 62 had it disabled by default behind the dom.webcomponents.enabled preference. Firefox 2 to 57 did not support it.
Safari supports Shadow DOM v1 from Safari 10 on macOS, and from Safari 11 on iOS and iPadOS. Safari 3.1 to 9.1 on macOS did not support it. iOS Safari 10 to 10.3 had partial support; iOS 3.2 to 9.3 did not support it.
Opera supports Shadow DOM v1 from Opera 40 on desktop, which is built on Chromium. Opera 9 to 39 did not support it. Opera Mobile supports Shadow DOM v1 from Opera Mobile 80 on; Opera Mobile 10 to 12.1 did not support it.
Samsung Internet supports Shadow DOM v1 from Samsung Internet 6.2 on. Samsung Internet 5 had partial support, and Samsung Internet 4 did not support it.
The legacy stock Android Browser supports Shadow DOM v1 from Android Browser 97 on. Android Browser 2.1 to 4.4.4 did not support it. Chrome for Android and Firefox for Android both support Shadow DOM v1 by default.
Internet Explorer never supported Shadow DOM v1 in any version. Pages that need the API in IE 11 have to load a polyfill such as the WebComponents.org webcomponents-bundle, which ships a JavaScript implementation of attachShadow and the slot element.
Note: Shadow DOM v1 styles, slots, and focus behave differently across browsers. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
Shadow DOM v1 ships nine encapsulation features that the v0 draft either did not have or shaped differently. They are the foundation that Lit, Stencil, Salesforce LWC, and many other component frameworks build on.
element.attachShadow({mode: 'open' | 'closed'}). Mode is required, which makes the access policy explicit.host.shadowRoot. Closed mode hides it from external scripts so only the code that attached it keeps the reference.<slot> element accepts light DOM children from the host and projects them into the shadow tree. Named slots use the slot attribute; the default slot catches the rest.slotchange at the end of a microtask when its assigned nodes change, so a component can react to host content updates without a MutationObserver.:host, :host(), and ::slotted() pseudo-classes give controlled hooks for styling the host and projected children.CSSStyleSheet across many instances through shadowRoot.adoptedStyleSheets, which is faster than re-parsing inline <style> blocks per instance.target retargeted to the host, while event.composedPath() still exposes the full path for components that opt in.<template shadowrootmode> attribute lets servers send shadow trees as HTML, so server-rendered Web Components hydrate without JavaScript. Chrome 90+, Edge 90+, Firefox 123+, and Safari 16.4+ support it.Shadow DOM v0 was a Chromium-only draft. Shadow DOM v1 is the standard every major browser ships. The two specs share the same idea but differ on the API surface, slot model, and lifecycle. The table below lines up the differences a developer is most likely to hit.
| Dimension | Shadow DOM v0 | Shadow DOM v1 |
|---|---|---|
| Spec status | Deprecated, removed from Chromium | Standard, in the W3C and WHATWG DOM Standard |
| Attach API | element.createShadowRoot() | element.attachShadow({mode}) |
| Mode parameter | Not applicable | Required: 'open' or 'closed' |
| Slot mechanism | <content> element with select="" CSS-style queries | <slot> element with name attribute |
| Multiple shadow roots | Allowed, then deprecated | One root per host element |
| Slot change events | Not available | slotchange fires on assigned-node updates |
| Browser support | Chromium only, removed | Chrome 53+, Edge 79+, Firefox 63+, Safari 10+, Opera 40+ |
Shadow DOM v1 support depends on a single API: Element.attachShadow. Three quick checks cover most production needs.
typeof Element.prototype.attachShadow === "function". It returns true if Shadow DOM v1 works.document.createElement("div").attachShadow({mode: 'open'}). A returned ShadowRoot object confirms the API is live; an exception means the browser does not support it."slot" in document.createElement("div"). The slot mechanism is the v1 distribution model; a true result means the browser ships v1, not v0.HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode"). The v1 API can ship before declarative shadow DOM does, so this catches the common gap on older Firefox.false, load github.com/webcomponents/polyfills with the webcomponents-bundle.js entry. The polyfill stamps a JavaScript-only attachShadow into the prototype.These checks each run on one browser at a time. To validate Shadow DOM v1 across every browser and OS combination your users have, TestMu AI gives you 3,000+ real browsers and devices to run the same checks on.
Shadow DOM v1 is one specification, but the encapsulation rules surface real cross-browser quirks. Here is what to watch for and how to handle each one.
shadowRoot.adoptedStyleSheets to share a constructable stylesheet across components.document.querySelector("button") ignores buttons inside any shadow tree. Test frameworks need a piercing API. How to handle it: In my experience this is the single biggest cross-browser pitfall when retrofitting tests onto a Web Components codebase. Selenium 4's getShadowRoot(), Playwright's default selectors, and Cypress's cy.shadow() each pierce differently, so pick one tool per repo.document.activeElement retargets to the host, not the focused node inside. How to handle it: Walk document.activeElement.shadowRoot.activeElement recursively when you need the deepest focus, and test tab order on every target browser.shadowRoot from outside JavaScript, but the same-realm code can still reach internals through event paths and attached references. How to handle it: Treat closed mode as a developer hint, not a sandbox. The web.dev Shadow DOM v1 guide explicitly recommends open mode.aria-labelledby across the boundary. How to handle it: Keep ARIA attributes on light DOM children where possible and use the ElementInternals API to expose role, value, and validation to assistive tech.<form> in the page head does not pick up a custom <input> defined inside a shadow tree without help. How to handle it: Use ElementInternals.setFormValue() with form-associated custom elements (Chrome 77+, Safari 16.4+, Firefox 98+) so the host element participates in the outer form.All Shadow DOM v1 version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance