Modern CSS Feature Support For Shadow DOM

Tracking the state of support for CSS features within and across the shadow DOM to provide visibility into feature parity, usage details, and outstanding issues and bugs.

:has()

Use With Caution Updated: Dec 17, 2025

Selector for selecting the parent or previous element based on detecting the presence of child elements or sibling relationships.

Baseline:
Newly
Functional:
Progressing
Usage:
Cross-Context

The :has() selector has mixed browser support for shadow DOM usage, with missing consensus on expected behavior. Cross-browser, :has() cannot cross the light/shadow boundary to peer into a different scope. Host-based selectors like :host:has() and :host(:has()) have inconsistent support across browsers. Only :host:has() is presently accepted in the spec.

Ranked caution due to mixed browser consensus — effective use is limited to elements within the same scope, without relying on host-based or cross-boundary selectors.

Web Platform Tests for :has()

View all tests for :has()
Chrome 147: Fails
Edge 146: Fails
Firefox 149: Fails
Safari 26.4: Fails
Anchor link for :has()

@property

Acceptable Support Updated: Dec 17, 2025

Allows for property type checking and constraining, setting default values, and defining whether or not a custom property can inherit values.

Baseline:
Newly
Functional:
Critical
Usage:
Light DOM Priority

Per current browser support, @property definitions can only exist in light DOM. However, applied defined properties in shadow DOM respect those definitions. This makes them usable for applications that are able to host a global stylesheet.

Web Platform Tests for @property

View all tests for @property
Chrome 147: Fails
Edge 146: Fails
Firefox 149: Fails
Safari 26.4: Fails
Anchor link for @property

@scope

Use With Caution Updated: Dec 19, 2025

Enables scoped styling with upper and lower boundaries, where proximity to defined scopes affects which rules win.

Baseline:
Newly
Functional:
Progressing
Usage:
Cross-Context

Global @scope cannot cross the shadow boundary to apply to shadow elements. Within shadow DOM, @scope works with :host and :host() as the scoping root, and implicit @scope (without a boundary) correctly scopes to the shadow root. Note that ::slotted() within @scope lacks test coverage and may have inconsistent support.

Ranked caution due to limited real-world testing with shadow DOM. While WPT tests pass and Firefox 131+ completes cross-browser support, some edge cases like ::slotted() in @scope remain unverified.

Web Platform Tests for @scope

View all tests for @scope
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Passes
Safari 26.4: Passes
Anchor link for @scope

Anchor Positioning

Not Recommended Updated: Apr 2, 2026

Positions elements relative to anchor elements anywhere on the page, independent of containing block layout.

Baseline:
Limited
Functional:
Progressing
Usage:
Cross-Context

Anchor positioning is spec'd to work within shadow DOM contexts; anchors can be named and positioned within the same shadow tree. Cross-shadow anchoring (referencing an anchor from a different shadow tree) presently has mixed browser support. The anchor-scope property for controlling anchor visibility across shadow boundaries shows similar browser inconsistencies.

Not recommended due to limited browser support, and specificially shadow DOM feature failures. Adoption likely should wait for fully Baseline cross-browser support. Strongly recommend a fallback strategy using positioning libraries like Floating UI.

Web Platform Tests for Anchor Positioning

View all tests for Anchor Positioning
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Passes
Safari 26.4: Passes
Anchor link for Anchor Positioning

Cascade layers

Supported Per Spec Updated: Dec 17, 2025

Allows for controlling the specificity and order of rule sets across stylesheets.

Baseline:
Widely
Functional:
Supported
Usage:
Cross-Context

Cascade layers can be defined and used independently within both light DOM and shadow DOM stylesheets with full support for shadow DOM selectors like ::slotted().

Shadow-defined cascade layers cannot interact with or impact global layer order, even with identical layer names, as each shadow root is isolated.

Web Platform Tests for Cascade layers

View all tests for Cascade layers
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Passes
Safari 26.4: Passes
Anchor link for Cascade layers

Color Scheme

Supported Per Spec Updated: Dec 17, 2025

Allows elements to define which color schemes they may be rendered in: light, dark, or prioritizing the order for both.

Baseline:
Widely
Functional:
Supported
Usage:
Cross-Boundary

The color-scheme property is inherited across the shadow boundary, allowing shadow DOM elements to respond to the document or an ancestor's color scheme. This enables automatic adaptation of page elements to the user's preferred color scheme, with form elements adjusting their appearance for improved contrast.

A shadow-defined color-scheme is also inheritable by slotted children.

Anchor link for Color Scheme

Container Size Queries

Acceptable Support Updated: Jan 23, 2026

Enable querying the size of a defined container and responding to that size by applying rulesets to its children.

Baseline:
Widely
Functional:
Critical
Usage:
Cross-Boundary

Essential access to query light DOM-defined containers from within the shadow DOM is supported.

Additionally, most other queries for :host, ::slotted(), and ::part() defined containers will work as expected.

Web Platform Tests for Container Size Queries

View all tests for Container Size Queries
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Passes
Safari 26.4: Fails
Anchor link for Container Size Queries

light-dark()

Use With Caution Updated: Dec 17, 2025

A color function for defining two values, the first responding to light mode and the second to dark mode based on user preference or in response to an explicit value on color-scheme.

Baseline:
Newly
Functional:
Supported
Usage:
Cross-Boundary

The light-dark() function works fully within shadow DOM contexts: it inherits correctly, works through custom properties, with ::slotted(), and when set directly within shadow DOM. Requires a color-scheme value to be set. Note that light-dark() only applies to color values.

Ranked caution due to Baseline newly available status (May 2024). Unsupporting browsers revert colors to initial values, risking severe visual breakage.

Anchor link for light-dark()

Native Nesting

Acceptable Support Updated: Dec 17, 2025

The ability to nest one style rule inside of another.

Baseline:
Newly
Functional:
Supported
Usage:
Cross-Context

Native CSS nesting works as expected within shadow DOM when applied to non-:host elements. However, nesting within :host selectors has mixed browser support: Safari versions earlier than 18.1 have known issues, nesting states on :host (e.g., :hover) fails, and the featureless & does not reference :host.

Web Platform Tests for Native Nesting

View all tests for Native Nesting
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Passes
Safari 26.4: Passes
Anchor link for Native Nesting

Popover API

Supported Per Spec Updated: Jan 13, 2026

A web API that enables promoting elements to the top layer, escaping containing blocks and superseding z-index layering, solving a common CSS pain point.

Baseline:
Newly
Functional:
Progressing
Usage:
Cross-Context

Popover works within shadow DOM contexts, both declaratively and via scripting. The trigger and the content must exist in the same context, though the content may be the light DOM of another component as long as its ID is unique.

Ranked progressing due to focus behavior inconsistencies: Firefox and Safari fail tests for focus handling inside shadow DOM popovers. Core popover functionality and shadow host focus delegation work correctly across all browsers.

Web Platform Tests for Popover API

View all tests for Popover API
Chrome 147: Passes
Edge 146: Passes
Firefox 149: Fails
Safari 26.4: Fails
Anchor link for Popover API