Variables, but Better — They Cascade and Update Live
Custom Properties
`--my-var: ...` defines a CSS custom property. `var(--my-var)` reads it. They inherit, cascade, and can be changed at runtime.
What you'll learn
- Declare and read custom properties
- Use them for design tokens
- Update them from media queries and JS
CSS custom properties — sometimes called “CSS variables” — let you name a value once and reuse it. Better than preprocessor variables: they cascade, inherit, and update at runtime.
Declare and Read
:root {
--brand: #6360ff;
--space-1: 0.5rem;
--space-2: 1rem;
--radius: 8px;
}
.btn {
background: var(--brand);
padding: var(--space-1) var(--space-2);
border-radius: var(--radius);
} Declared on :root means available everywhere.
Fallbacks
color: var(--text, #111); /* if --text isn't set, use #111 */ The second argument is a fallback. Fallbacks can be other custom
properties: var(--text, var(--fg, #111)).
Local Scope
Custom properties cascade. Set one in a component, and only that subtree sees the local value:
.dark-section {
--bg: #111;
--text: white;
background: var(--bg);
color: var(--text);
} Inside .dark-section, descendants see the local values. Outside,
they don’t.
Update at Runtime
Change a property in a media query — everything that uses it updates:
:root {
--bg: white;
--text: #111;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #111;
--text: white;
}
}
body {
background: var(--bg);
color: var(--text);
} One swap; the whole site re-themes.
From JavaScript
document.documentElement.style.setProperty("--brand", "tomato");
const value = getComputedStyle(document.documentElement).getPropertyValue("--brand"); Useful for theming, user preferences, and dynamic effects.
Design Tokens
The killer use case — a small set of named values that describe your design system:
:root {
/* color */
--color-brand: #6360ff;
--color-text: #111;
--color-bg: white;
--color-muted: #6b7280;
/* spacing */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 1rem;
--space-4: 2rem;
/* type */
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.5rem;
/* radius */
--radius-sm: 4px;
--radius: 8px;
--radius-lg: 16px;
} Components reference tokens; never raw values. Need to change the brand color? Edit one line.
Up Next
Math in CSS — calc(), min, max, clamp.