v148 · CSS · Web Components · demo

Shadow DOM Theming

Three named CSS modules — theme-default, theme-dark, theme-warm — that can be adopted by shadow roots at runtime. All components re-style when the active specifier changes, no re-render needed.

Chrome 148+ origin trial — Declarative CSS Module Scripts. In unsupported browsers the demo uses a JS class-based fallback to simulate the same effect.

Active module: theme-default

<!-- Three named theme modules defined once in <head> -->
<style type="module" specifier="theme-default">
  :host { background: #fdfcf8; border: 2px solid #000; ... }
  .widget-value { color: #000; }
</style>

<style type="module" specifier="theme-dark">
  :host { background: #111; border: 2px solid #444; ... }
  .widget-value { color: #fff; }
</style>

<!-- Each shadow root adopts a specifier by name -->
<stat-widget>
  <template shadowrootmode="open"
            shadowrootadoptedstylesheets="theme-default">
    <p class="widget-title"><slot name="title"></slot></p>
    <p class="widget-value"><slot name="value"></slot></p>
  </template>
</stat-widget>

<!-- Swap themes by updating the adoptedstylesheets attribute -->
document.querySelectorAll('stat-widget').forEach(el => {
  el.shadowRoot.adoptedStyleSheets =
    document.getCSSModule('theme-dark');
});

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗