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.
<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.
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.
part="name" to expose them for styling. This provides a well-defined styling API.
Demo:
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.
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.
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
- Leverage Inheritable Styles for consistent typography across your application
- Use CSS Variables for themeable components - it's the most flexible and maintainable approach
- Expose ::part selectors for specific elements that users should style
- Use Adopted Stylesheets when you have many instances of the same component
- Avoid Direct Injection unless you're building developer tools or plugin systems
- Document your styling API - make it clear what CSS variables and parts are available