Skip to content

CSS Custom Properties in Shadow DOM — Complete Guide

DodaTech Updated 2026-06-28 1 min read

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

  1. Not providing default values with var()
  2. Setting custom properties inside the shadow tree instead of on the host
  3. Using custom properties for non-themable values

Practice Questions

  1. How do custom properties cross the shadow boundary? They inherit from the host element into the shadow tree.
  2. 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