🎨 five Shadow DOM Styling Options

A comprehensive guide to styling Web Components with Shadow DOM

Notes:

shadowRoot boundary global styles can't style Web Component* â–¼ â–¼ â–¼ â–¼ â–¼ * Yes they can! Use CSS properties, the CSS ::part selector or adopted Stylesheets â–² â–² â–² â–² â–² Web Component styles can't taint global page

Table of Contents

1. Inheritable Styles

Certain CSS properties naturally cascade through the Shadow DOM boundary.
These are properties that inherit by default, such as color, font-family, font-size, line-height, etc.

Inheritable properties flow from the Global / Light DOM into the shadow DOM unless explicitly overridden inside the shadow DOM.

<demo-inheritable>:

2. CSS Custom Properties (CSS Variables)

CSS Custom Properties (variables) pierce the Shadow DOM boundary. This is the most flexible and recommended way to create themeable Web Components. You define variables in the Global / Light DOM, and they can be used inside the shadow DOM.

CSS variables are inherited properties, so they automatically flow into shadow DOM. This makes them perfect for theming systems.

Demo:

3. ::part Selector

The ::part() pseudo-element allows you to select and style elements inside a shadow DOM that have been explicitly exposed using the part attribute. This gives component authors control over what can be styled from outside.

The component author must explicitly mark elements with part="name" to expose them for styling. This provides a well-defined styling API.

Demo:


/* Inside Shadow DOM - exposing parts */
Header Section
Content Section
Footer Section

4. Adopted Stylesheets

Constructable Stylesheets (via adoptedStyleSheets) allow you to create stylesheet objects in JavaScript and share them across multiple shadow roots. This is efficient for applying the same styles to multiple components.

Stylesheets created this way can be shared across multiple shadow roots without duplicating the CSS text, making them memory-efficient.

Demo:

Change the one stylesheet all 3 cards have adopted:

5. Inject Own Stylesheet in Open Shadow Roots

For components with mode: 'open', external JavaScript can directly access and modify the shadow DOM, including injecting new stylesheets. This is useful for plugins, themes, or debugging tools.

This only works with open shadow roots. Closed shadow roots cannot be accessed from outside. This technique is powerful but should be used carefully as it bypasses the component's encapsulation.

Demo:

📊 Comparison of Methods

Method Control Flexibility Use Case
Inheritable Styles Limited Low Basic typography, colors
CSS Variables Component defines High Theming, customization
::part Selector Component defines Medium Specific element styling
Adopted Stylesheets Component owns High Sharing styles, performance
Direct Injection External code Very High Plugins, debugging, themes

✨ Best Practices