CSS Custom Properties in Shadow DOM — Complete Guide
In this tutorial, you will learn about CSS Custom Properties in Shadow Dom. We cover key concepts, practical examples, and best practices to help you master this topic.
CSS custom properties inherit into shadow trees, providing a theming API that crosses the Encapsulation boundary without breaking style isolation.
What You'll Learn
- How CSS custom properties cross the shadow boundary
- How to define theming APIs with custom properties
- How to provide and override defaults
- Best practices for custom property APIs
Why It Matters
Style encapsulation prevents external CSS from targeting shadow elements. Custom properties are the designated escape hatch for theming.
flowchart LR A[Host Page CSS] --> B[--primary: blue] B --> C[Shadow DOM] C --> D[var(--primary)] D --> E[Component uses theme]
Theming via Custom Properties
class ThemeCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
--card-bg: white;
--card-border: #ddd;
--card-text: #333;
--card-radius: 8px;
--card-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card {
background: var(--card-bg);
border: 1px solid var(--card-border);
color: var(--card-text);
border-radius: var(--card-radius);
box-shadow: var(--card-shadow);
padding: 16px;
}
</style>
<div class="card"><slot></slot></div>
`;
}
}
customElements.define('theme-card', ThemeCard);
Expected output: Users customize via: theme-card { --card-bg: #f0f8ff; --card-border: #4682b4; --card-text: #003366; }
Property Inheritance Chain
Custom properties follow the CSS cascade and inherit through shadow boundaries.
// Set on custom element (affects all instances inside)
document.querySelector('#app').style.setProperty('--primary', '#e74c3c');
// Set on specific instance (affects that instance only)
document.querySelector('theme-card').style.setProperty('--card-bg', '#fff3cd');
Common Mistakes
- Not providing default values with var()
- Setting custom properties inside the shadow tree instead of on the host
- Using custom properties for non-themable values
Practice Questions
- How do custom properties cross the shadow boundary? They inherit from the host element into the shadow tree.
- How do you provide a default?
var(--property, default-value).
Mini Project
Build a card component with 10+ themeable properties via CSS custom properties. Include a theme switcher that changes all properties at once.
What's Next
Lesson 9: CSS Parts in Shadow DOM
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro