--main-bg, --main-color and --main-border are declared once on the surrounding container and consumed via var() on each box.
Aa background + color + border --main-bg: #2c3e50 · --main-color: white · --main-border: 3px solid #1a252f background: var(--main-bg); color: var(--main-color); border: var(--main-border) | Aa reused for border only --main-border: 3px solid #1a252f border: var(--main-border) | Aa reused for text color --main-bg: #2c3e50 color: var(--main-bg) | Aa literal (no var, for comparison) (no custom property used) background: #2c3e50 (literal) |
Each box references a custom property that was never declared; the fallback (second argument to var()) is used instead.
Aa color fallback --undefined-bg: (not declared) → fallback #8e44ad background: var(--undefined-bg, #8e44ad) | Aa length fallback --undefined-padding: (not declared) → fallback 16px padding: var(--undefined-padding, 16px) | Aa nested fallback chain --undefined-a, --undefined-b: (not declared) → fallback #d35400 var(--a, var(--b, #d35400)) | Aa no fallback (uses initial) --totally-undefined: (not declared) → initial value background: var(--totally-undefined) |
--accent is declared once on the outer container. The second box overrides it locally; the override does not leak to its siblings.
Aa inherited (no override) --accent: #2980b9 (inherited) background: var(--accent) → inherited | Aa local override --accent: #c0392b (local override) --accent: #c0392b (local) | Aa sibling still inherits original --accent: #2980b9 (inherited, unaffected) background: var(--accent) → unaffected | Aa --accent: unset (still inherits) --accent: #2980b9 (via unset → inherit) --accent: unset; background: var(--accent) |
Per spec, a custom property that references itself (directly or through a chain) becomes invalid instead of looping forever; a fallback or the property's initial value is used.
Aa direct cycle, with fallback --loop-a ↔ --loop-b: cyclic → invalid → fallback #7f8c8d --loop-a: var(--loop-b); --loop-b: var(--loop-a); background: var(--loop-a, #7f8c8d) | Aa self-reference — always invalid --self: self-referential → invalid (the fallback inside --self's OWN definition does not rescue it — matches Chrome/Firefox) --self: var(--self, #e74c3c); background: var(--self) (no fallback here) | Aa one-directional chain (not cyclic) --chain-a → --chain-b: #27ae60 (resolved, not cyclic) --a: var(--b); --b: #27ae60 → resolves | Aa multi-hop chain --x1 → --x2 → --x3: #f39c12 (resolved) --x1→--x2→--x3: #f39c12 |
The same card markup and CSS rules render two different themes purely by changing custom property values on the wrapping element — no duplicated rules.
Light ThemeThis card uses the component's default custom property values. --card-bg: white · --card-fg: #222 · --card-accent: #2c3e50 · --card-muted: #666 (defaults) | Dark ThemeSame markup and rules — only the custom property values differ. --card-bg: #1a1a2e · --card-fg: #eee · --card-accent: #e94560 · --card-muted: #aaa (overridden inline) |