localwebadvisor
WIKI← Wiki home

What Are CSS Variables?

By FayUpdated Jul 10, 2026EVERGREEN
⚡ THE ANSWER

CSS variables, called custom properties, are named values you define once in your stylesheet and reuse it. You declare one with a double-dash name, like --color-primary: #1A73E8, and apply it anywhere with the var() function, such as color: var(--color-primary). Because the value lives in one place, changing it updates every rule that references it. Unlike preprocessor variables, CSS variables are live in the browser, so they can be read and changed with JavaScript and cascade through the page, making them ideal for theming, dark mode, and maintainable stylesheets.

Official name
CSS custom properties (MDN)
Syntax
Declared as --name: value; used with var(--name)
Live in browser
Can be read and changed at runtime with JavaScript, unlike Sass variables
They cascade
Inherit and can be overridden per element, following normal CSS rules
Browser support
Supported in all modern browsers (MDN, caniuse)

What CSS variables are #

CSS variables, whose formal name is custom properties, let you store a value under a name and reuse it across your stylesheet. You define one with a leading double dash, for example --space-md: 16px, and then reference it with the var() function wherever you need that value. The point is a single source of truth: define the brand color or a spacing step once, use it everywhere, and change it in one place to update the whole site. This makes stylesheets dramatically easier to maintain, because values that used to be scattered as repeated literals become named references. Custom properties are a native part of CSS, supported by every modern browser, so they need no build tools or preprocessors to work. They are the practical web implementation of design tokens, and we lean on them heavily to keep the sites we build consistent and easy to update, a core habit in both /services/web-design and /services/web-app-development.

How to declare and use them #

Declaring a CSS variable looks like a normal property but with a custom double-dash name, and it is usually defined on the :root selector so it is available globally. You then consume it anywhere a value is expected using var(). The var() function also accepts a fallback: var(--color-accent, #cccccc) uses the fallback if the variable is undefined, which guards against mistakes. Variable names are case-sensitive and can describe either raw values, like --blue-500, or purpose, like --color-text. Grouping related variables together at the top of your stylesheet gives you a clear, editable control panel for the whole site's look. Because they are ordinary CSS, they work in any selector and combine naturally with the rest of your styles. This simplicity is a big part of their appeal for small-business sites, where a tidy set of variables makes future tweaks quick and safe rather than a risky search-and-replace across many files. Because the syntax is native CSS, there is nothing to install or compile; the variable simply works the moment the browser reads it.

Declaring and using variables
:root {
  --color-primary: #1A73E8;
  --space-md: 16px;
  --radius: 8px;
}

.button {
  background: var(--color-primary);
  padding: var(--space-md);
  border-radius: var(--radius);
}

Why they beat hardcoded values #

Before custom properties, developers repeated the same literal values, a hex color, a pixel size, throughout their CSS. When something needed to change, they had to find and replace every occurrence, missing some and creating inconsistencies. CSS variables fix this by centralizing each value under a name, so the brand blue is defined once and updated once. This eliminates the drift where one button is slightly the wrong shade because a value was typed by hand. It also makes intent clearer: var(--color-danger) reads more meaningfully than a bare red hex code, so the next developer understands why it is there. Maintenance becomes faster and safer, which matters when a small business needs a quick brand tweak without risking the whole site. This is the same consistency discipline behind design tokens, and using variables is how we make sure a site stays visually coherent as it grows, part of the durable foundations we build in /services/ui-ux-design.

The power of the cascade #

What sets CSS variables apart from preprocessor variables is that they follow the normal CSS cascade and inheritance. A variable defined on an element is available to all its descendants, and you can override a variable for a specific section simply by redefining it on a container. This means a single variable can hold different values in different parts of the page, a card component might set --padding locally without affecting the rest of the site. It also enables elegant patterns: define theme variables on :root, then override them inside a .dark class or a specific component to change everything nested within. Because the browser resolves variables live, these overrides take effect instantly and predictably. This cascading behavior is far more flexible than Sass variables, which are compiled away before the browser ever sees them. We use scoped variable overrides to build components that adapt to context automatically, a technique that keeps interfaces both consistent and flexible in the work we do under /services/web-design.

Powering dark mode and theming #

CSS variables are the standard, clean way to build dark mode and other themes. You define semantic variables, --color-background, --color-text, --color-surface, on :root for the default theme, then provide a second set of values under a selector like [data-theme="dark"] or a prefers-color-scheme media query. Switching the theme changes only those variable values, and because every component references the variables rather than fixed colors, the entire interface re-themes at once with no per-element edits. This is vastly simpler than the old approach of maintaining duplicate stylesheets. The same technique supports high-contrast accessibility themes, seasonal brand variations, or letting users pick an accent color. Because the change is just a set of variable values, you can even persist a user's choice and apply it instantly. Offering a polished dark mode signals a modern, well-built site, and we implement it with custom properties so it stays maintainable, reinforcing the consistent brand systems established in /services/branding-design.

Changing variables with JavaScript #

Unlike Sass or Less variables, which vanish at build time, CSS custom properties exist live in the browser, so JavaScript can read and change them at runtime. A single line can update a variable on the root element, and every rule using that variable updates instantly, no stylesheet swapping required. This unlocks interactive theming, a color picker that recolors the site as the user drags, a font-size control for accessibility, or animations driven by changing variable values. It also lets you pass dynamic data into CSS, such as setting a progress bar's width or a chart's dimensions from script. Because the browser handles the recalculation efficiently, this is both simple and performant. This bridge between JavaScript and CSS is one of the most powerful aspects of custom properties, and we use it to build responsive, user-adjustable interfaces in /services/web-app-development, where letting users personalize the experience adds real value without heavy or fragile code.

Updating a variable with JS
// Change the primary color live for the whole page
document.documentElement.style
  .setProperty('--color-primary', '#E8501A');

// Read a variable's current value
const color = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-primary');

CSS variables versus Sass variables #

People often ask how CSS custom properties differ from preprocessor variables like those in Sass. The key difference is timing and reach. Sass variables are resolved when your CSS is compiled, before the browser ever runs, so by the time the page loads they are gone, replaced by fixed values. They are handy for build-time logic but cannot change at runtime, cannot be read by JavaScript, and do not cascade. CSS variables live in the browser: they cascade, inherit, respond to media queries, and can be changed on the fly with script. In practice the two coexist well, Sass for build-time computation and organization, custom properties for anything that must be dynamic or themeable. For most modern sites, custom properties handle the values that matter for theming and maintenance, while a preprocessor, if used at all, handles convenience features. Choosing the right tool for each job keeps stylesheets both powerful and clean, a balance we strike in every front end we build.

Practical tips and pitfalls #

A few practices make CSS variables reliable. Define global variables on :root so they are available everywhere, and use clear, purpose-based names for anything theme-related. Provide fallbacks in var() for values that might be missing. Remember that custom properties inherit, so a variable set on a parent affects children unless overridden, useful, but occasionally surprising. Note that they cannot be used in media query conditions themselves, only in the declarations inside them, and they are case-sensitive. Avoid overusing variables for one-off values that never repeat, which just adds indirection. For a small business site, a focused set of variables covering colors, spacing, type, and radius usually delivers most of the benefit without clutter. We set these up thoughtfully at the start of a build so the site has a clean, documented control surface for its look, making future changes fast and low-risk, part of the maintainable approach behind every project in /services/web-design.

FAQ

What is the difference between CSS variables and Sass variables?

Sass variables are resolved at build time and disappear before the browser runs, so they cannot change dynamically. CSS variables, or custom properties, live in the browser: they cascade, inherit, respond to JavaScript, and can change at runtime. That live behavior is why CSS variables power theming and dark mode, while Sass handles build-time logic.

How do I declare a CSS variable?

Define it with a double-dash name, usually on :root so it is global, like --color-primary: #1A73E8. Then use it anywhere with var(), such as color: var(--color-primary). You can add a fallback, var(--color-primary, blue), which applies if the variable is undefined.

Can JavaScript change CSS variables?

Yes. Because custom properties are live in the browser, JavaScript can update one with element.style.setProperty('--name', value), and every rule using that variable updates instantly. This enables interactive theming, user-adjustable font sizes, and passing dynamic values into CSS without swapping stylesheets, something Sass variables cannot do.

Do CSS variables work in all browsers?

Yes, all modern browsers support CSS custom properties (MDN). Only very old browsers like Internet Explorer lack support, which is rarely a concern in 2026. If you must support ancient browsers, provide a plain fallback value before the var() line so those browsers use the static value.

Why are CSS variables good for dark mode?

Because you define semantic variables like --color-background and --color-text once, then override their values under a dark theme selector. Every component references the variables, so switching themes updates the whole site at once with no per-element edits, making dark mode simple to add and maintain.

Can I use CSS variables inside media queries?

You can use them in the declarations inside a media query, but not in the media query condition itself, browsers do not evaluate custom properties there. A common pattern is redefining a variable's value inside a media query so layouts or spacing adjust responsively while components keep referencing the same variable.

How Local Web Advisor checks this for you

Is your own website getting web dev right?

Our free AI audit scans your site and tells you — in plain English — exactly what to fix for web dev and seven other areas, with the business impact and the fix for each. No login needed to start.

Run my free website audit →

Was this helpful?