v153 · web components · css · ship status divergent
Declarative Shadow DOM 'shadowrootadoptedstylesheets'
An extension of CSS module scripts that lets you define and share stylesheets declaratively — using <style type="module"> — and apply them to Declarative Shadow DOM via the new shadowrootadoptedstylesheets attribute, without any JavaScript required.
is_released: false with an active Origin Trial running from Chrome 148 through 153. See browser compatibility for both attributed sides.
at a glance
| Ship status | Divergent: milestone listing recorded "Enabled by default" in Chrome 153 (verified 2026-07-28); API record reports unreleased, Origin Trial 148–153 (queried 2026-10-07) — see banner and browser compatibility |
|---|---|
| Origin trial | Chrome 148 – 153 (desktop, Android, WebView) |
| Standards | WICG / WHATWG proposal |
| Explainer | MSEdge Explainers — Declarative adopted stylesheets |
| Issues | WICG/webcomponents #939 · WHATWG/html #10673 |
| Specification PR | WHATWG HTML PR #12339 |
| ChromeStatus | 4790543041298432 — Declarative Shadow DOM 'shadowrootadoptedstylesheets' |
why it exists
Declarative Shadow DOM (DSD) lets you ship server-rendered shadow roots without JavaScript, but it has a stylesheet-sharing problem. When multiple shadow roots need the same CSS, authors must inline it inside every <template shadowrootmode="open">. A component used 100 times means 100 copies of the same styles in the HTML payload — inflating page weight and increasing both latency and memory use. The imperative equivalent (adoptedStyleSheets) solves this for JavaScript-instantiated shadow roots but can't help with DSD. Declarative CSS module scripts bridges the gap: define a stylesheet once in a <style type="module"> and reference it by name across any number of DSD instances.
Syntax
<!-- Define a reusable inline CSS module -->
<style type="module" specifier="sheet-id">
:host { display: block; }
</style>
<!-- Adopt the module declaratively in Shadow DOM -->
<host-element>
<template shadowrootmode="open" shadowrootadoptedstylesheets="sheet-id">
<slot></slot>
</template>
</host-element>
The declarative style sharing capability introduces two primary markup surfaces:
1. Declarative Shadow Root attribute
<template shadowrootmode="open|closed"
shadowrootadoptedstylesheets="<specifier-or-url> [<specifier-or-url>...]">
<!-- shadow content -->
</template>
The shadowrootadoptedstylesheets attribute is specified on a <template> element that defines a declarative shadow root (using shadowrootmode). Its value is an ordered, space-separated set of CSS module specifiers or URL strings.
2. Inline CSS module script definition
<style type="module" specifier="<module-specifier>">
/* Reusable CSS module declarations */
</style>
The <style type="module"> element defines an inline CSS module associated with a specifier identifier. The stylesheet can be resolved by name anywhere in the same document scope where module scripts resolve.
Inputs and outputs
Inputs: shadowrootadoptedstylesheets accepts a string containing zero or more space-delimited module specifiers or valid URLs. <style type="module"> accepts a specifier string attribute that registers the inline stylesheet under that specifier token, and CSS text as its text content.
Outputs: As a declarative HTML parser feature, there is no direct JavaScript return value. When the HTML parser encounters shadowrootadoptedstylesheets, each referenced stylesheet is resolved and appended to the newly created shadow root's adoptedStyleSheets sequence in the specified order, populating shadowRoot.adoptedStyleSheets with the constructed CSSStyleSheet objects.
Errors and lifecycle
Errors: For the shadowrootadoptedstylesheets attribute on <template>, the explainer and WHATWG specifications align error handling with module script resolution. If an unknown specifier cannot be resolved or a network fetch fails, no synchronous JavaScript exception is thrown by the HTML parser; rather, failed module requests result in loading errors tracked per module script error semantics, and the shadow root continues parsing without the failed stylesheet. Empty or invalid CSS rules inside <style type="module"> are handled via standard CSS resilient parsing without throwing exceptions.
Lifecycle: Module stylesheets are fetched and parsed according to module map caching rules. When multiple Declarative Shadow DOM roots reference identical specifiers, only a single CSSStyleSheet instance is allocated and shared among all referencing shadow roots. Preloading stylesheets via <link rel="modulepreload" as="style"> in the document head avoids late fetches and layout shifts during streaming rendering.
Examples
The following example demonstrates defining a reusable card stylesheet once and adopting it across multiple declarative shadow roots without duplicating CSS text across component instances:
<!-- Define a reusable card stylesheet -->
<style type="module" specifier="card-styles">
:host { display: block; border: 1px solid #ccc; padding: 1rem; }
h2 { margin: 0 0 0.5rem; }
</style>
<my-card>
<template shadowrootmode="open"
shadowrootadoptedstylesheets="card-styles">
<h2>Card Title</h2>
<p>Card content here.</p>
</template>
</my-card>
<my-card>
<template shadowrootmode="open"
shadowrootadoptedstylesheets="card-styles">
<h2>Another Card</h2>
<p>Same styles, one definition.</p>
</template>
</my-card>
Multiple adopted stylesheets
<style type="module" specifier="base">
:host { box-sizing: border-box; }
</style>
<style type="module" specifier="theme">
:host { color: var(--primary, #333); }
</style>
<my-widget>
<template shadowrootmode="open"
shadowrootadoptedstylesheets="base theme">
<slot></slot>
</template>
</my-widget>
Origin trial token setup (Chrome 148–153)
<meta http-equiv="origin-trial" content="YOUR_TOKEN_HERE">
Source: blink-dev Intent to Experiment — Declarative CSS module scripts.
browser compatibility
The Chrome 153 milestone listing previously categorized this feature under "Enabled by default" on 2026-07-28. However, when queried on 2026-10-07, the ChromeStatus API record (feature 4790543041298432) reports is_released: false and lists the feature under milestone 148 as an active Origin Trial running through milestone 153 (desktop, Android, and WebView). The table below documents the engine positions and verified implementation status:
| Browser / Engine | Status | Evidence |
|---|---|---|
| Chrome (Desktop & Android) | Listing: "Enabled by default" 153 (verified 2026-07-28); record: Origin Trial 148–153, is_released: false (queried 2026-10-07) | ChromeStatus 4790543041298432; Issue 448174611 |
| Firefox | No signal (ongoing discussions) | Mozilla standards-positions #1081 |
| Safari / WebKit | No signal | WebKit standards-positions #407 |
| W3C TAG | Issues addressed | TAG review #1000 · TAG review #1195 |
security and privacy
- Style isolation:
shadowrootadoptedstylesheetsmaintains strict Shadow DOM encapsulation; stylesheets adopted by shadow roots do not leak styles into the outer document or into sibling shadow roots. - CORS and module script security: External CSS module scripts imported via URLs follow standard module fetch security models, requiring appropriate Cross-Origin Resource Sharing (CORS) headers for cross-origin assets.
- No executable script injection: CSS modules contain only CSS styling rules and cannot execute arbitrary JavaScript, preventing cross-site scripting vulnerabilities associated with dynamic script loading.
see also
- MSEdge Explainers — Declarative adopted stylesheets for shadow DOM
- WICG/webcomponents #939 — Declarative CSS module scripts discussion
- WHATWG HTML PR #12339 — Module Stylesheet link tags
- web.dev — Declarative Shadow DOM
- chromestatus — Declarative Shadow DOM 'shadowrootadoptedstylesheets' (4790543041298432)
- chrome-platform-showcase — live demo