CSS Variables (Custom Properties)
Custom properties — usually called CSS variables — store a value once and reuse it everywhere. Change the variable, and every use updates. Unlike variables in preprocessors, they live in the browser: they cascade, inherit, can be changed by media queries and JavaScript, and power theming and dark mode.
Declaring and using a variable
A custom property's name starts with two hyphens and is case-sensitive. Read it with var(). Declaring variables on :root makes them available everywhere, because they inherit.
Fallback values
The second argument to var() is used when the variable isn't set. Fallbacks can themselves contain var().
Scoping: variables cascade
Redefining a variable on a more specific selector changes it for that element and its descendants. One component, many variants — each only changes the variable.
Variables in media queries and states
Change the values inside a media query and every rule that uses them responds. Variables can't be used in a media query condition itself, though.
Theming and dark mode
Lesson 46 builds a complete light/dark theme on this idea.
Changing variables with JavaScript
JavaScript sets a variable with element.style.setProperty("--level", value) and reads one with getComputedStyle(element).getPropertyValue("--level"). The CSS does the rest.
Typed variables with @property
Normally a custom property is just text, so the browser can't animate it. Registering it with @property gives it a type, which makes smooth transitions and animations of the variable possible.
Things to know
- Variables hold any value — colours, lengths, whole shorthand values — but can't be used for property names or selectors.
- If a variable holds an invalid value for where it's used, the property falls back to its inherited or initial value (not to an earlier declaration).
- Name variables by purpose (
--color-text,--space-lg) rather than by value (--blue), so they still make sense after a redesign.