Custom Properties and Constructable Stylesheets
CSS custom properties (also called CSS variables) are the primary theming API for web components. Unlike regular CSS rules, custom properties inherit through shadow boundaries. The host element or any ancestor can declare --color: blue, and the shadow root can read it with color: var(--color, defaultValue). The second argument is the fallback, used when the property is not set.
/* Page or host sets the token */themed-badge { --badge-bg: #7c3aed; --badge-color: white;}
/* Shadow root reads it */span { background: var(--badge-bg, #6b7280); color: var(--badge-color, white);}This inheritance is intentional: custom properties were designed to punch through encapsulation. Everything else (selectors, cascade) stops at the shadow boundary, but -- variables flow freely.
Constructable Stylesheets
Section titled “Constructable Stylesheets”Constructable Stylesheets let you create a CSSStyleSheet object in JavaScript, populate it once with .replaceSync(), and then share that single object across many shadow roots by assigning it to shadowRoot.adoptedStyleSheets. Each shadow root that adopts the sheet gets the styles without duplicating the parsed CSS in memory.
const sheet = new CSSStyleSheet();sheet.replaceSync('span { font-weight: bold; color: steelblue; }');
class MyEl extends HTMLElement { connectedCallback() { var shadow = this.attachShadow({ mode: 'open' }); shadow.adoptedStyleSheets = [sheet]; }}This is particularly useful in design systems where dozens of components share a common base stylesheet. Parse once, adopt everywhere.
Live Demo
Section titled “Live Demo”The demo below defines a <themed-badge> element whose background and text color are driven entirely by CSS custom properties set on the host from the page stylesheet. Change the --badge-bg value in the CSS panel to retheme without touching the component code.