What CSS Variables Are
CSS variables, also known as custom properties, let you define a value once and reuse it anywhere in your stylesheet. Instead of searching for every instance of a color or spacing value to update, you change it in one place and everything referencing it updates automatically.
Variables always start with two dashes, such as --brand-color or --base-spacing. You apply them using the var() function.
:root { --brand-color: #3b82f6; --base-font-size: 16px;}button { background-color: var(--brand-color); font-size: var(--base-font-size);}
Every button on the page shares the same color and size. Changing --brand-color once updates all of them instantly.
Declaring Variables
Global variables with :root
The :root pseudo-class targets the highest-level element in the document, making any variable declared inside it available everywhere. It is the standard place for design tokens: the colors, fonts, and spacing values that define a consistent look across a site.
:root { --surface: #f9fafb; --text-primary: #111827; --accent: #6366f1; --radius: 8px;}
Local variables for components
Variables can be scoped to a specific selector. One declared inside .card applies only to that element and its children, keeping component-specific values self-contained.
.card { --card-gap: 24px; --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); padding: var(--card-gap); box-shadow: var(--card-shadow);}
Using Variables with var()
To apply a variable, pass its name to var().
body { background: var(--surface); color: var(--text-primary);}a { color: var(--accent);}
Fallback values
var() accepts an optional second argument used when the variable is not defined.
.badge { background: var(--badge-color, #6366f1); color: var(--badge-text, white);}
If --badge-color has not been declared, the element falls back to #6366f1. Fallbacks are especially useful when building reusable components that may be dropped into a page without a full set of variables defined.
Dynamic Variables
Theming with light and dark mode
Because variables can be overridden at different scopes, implementing a theme switch only requires redefining the variable values, not rewriting any of the property declarations that use them.
.light-mode { --surface: #ffffff; --on-surface: #111827;}.dark-mode { --surface: #1f2937; --on-surface: #f9fafb;}body { background: var(--surface); color: var(--on-surface);}
Toggling a class on the body element switches the entire theme. The background and color declarations never need to change.
Updating variables with JavaScript
CSS variables live in the DOM and can be changed at runtime using setProperty.
document.documentElement.style.setProperty('--accent', '#f59e0b');
This updates --accent globally, affecting every element that references it. The change is immediate and requires no page reload. It is the mechanism behind live theme pickers, animated color transitions, and any interface that adapts to user input.
Variables in media queries
Variables can be redefined inside a media query to adapt a design to different screen sizes without duplicating the property declarations.
:root { --body-size: 16px; --heading-size: 32px;}@media (max-width: 600px) { :root { --body-size: 14px; --heading-size: 22px; }}p { font-size: var(--body-size); }h1 { font-size: var(--heading-size); }
Both elements scale on smaller screens without any additional rules targeting them directly.
Best Practices
Declare global design tokens in :root and use component-level variables for values that belong to a specific block. Always provide fallback values for variables that may not be defined, particularly in reusable components intended to work in isolation. Use variables inside media queries to keep responsive adjustments centralized rather than scattered across individual selectors.
Avoid reaching for a variable every time you need a one-off value. Variables add the most value when the same piece of information would otherwise appear in multiple places. If a value is used only once, a direct declaration is simpler and easier to read.
See you soon.
[…] CSS Variables: Writing Smarter, More Maintainable Stylesheets […]
[…] shadow color accepts any CSS color value, so you are not limited to black. Hex, RGB, RGBA, and HSL all work, which means you can […]
[…] Variables: https://datalad.co.uk/css-variables-writing-smarter-more-maintainable-stylesheets/ […]