← all posts
2026-08-20·10 min readCSSTheming

CSS Variables (Custom Properties): A Practical Guide

How to create and use CSS variables, why they beat preprocessor variables, and how to build theming and dark mode with them, with copy-paste examples.

S
Saurabh Bhayana
Web developer & SEO specialist
// KEY TAKEAWAYS
  • CSS variables (custom properties) are defined with -- and read with the var() function.
  • They're usually declared on :root so they're available everywhere.
  • Unlike Sass variables, CSS variables are live in the browser and can change at runtime.
  • That live nature makes them perfect for theming and dark mode.
  • You can override them per component or per media query to change a whole design.

CSS variables, officially custom properties, let you store values like colors and spacing once and reuse them everywhere. Change one line and your whole design updates. They're also the cleanest way to build theming and dark mode. Here's how to use them well.

How to create a CSS variable

Declare a variable with two dashes, and read it with the var() function. Most people declare their variables on :root, the top of the document, so they're available everywhere.

css
:root {
  --accent: #38bdf8;
  --space: 1rem;
  --radius: 12px;
}

.button {
  background: var(--accent);
  padding: var(--space);
  border-radius: var(--radius);
}

Now the accent color lives in one place. Change --accent and every element using it updates instantly.

Fallback values

var() accepts a second argument, a fallback used if the variable isn't defined. Handy for components that might be used outside your theme.

css
color: var(--text-color, #333); /* uses #333 if --text-color is unset */

CSS variables vs Sass variables

If you've used Sass, you might wonder why CSS variables matter. The difference is huge: Sass variables are compiled away before the browser sees them, they're static. CSS variables are live in the browser, so they can change at runtime with JavaScript, media queries, or a class, which unlocks theming.

Sass variableCSS variable
Exists at runtime?No (compiled away)Yes (live in browser)
Can change dynamically?NoYes
Good for theming?LimitedExcellent
Needs a build step?YesNo

Building dark mode with CSS variables

This is where CSS variables shine. Define your colors as variables, then override them under a dark-mode selector or media query. Nothing else in your CSS changes.

css
:root {
  --bg: #ffffff;
  --text: #111827;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b0f1a;
    --text: #e5e7eb;
  }
}
body { background: var(--bg); color: var(--text); }
Tip

You can also toggle themes with a class (like <html data-theme="dark">) and override the variables under that selector. That lets users pick a theme manually, not just follow the system setting.

Scoping variables to components

Variables cascade like any CSS, so you can redefine one on a specific element to change just that subtree. Great for component variants without new class soup.

css
.card { --pad: 1rem; padding: var(--pad); }
.card.spacious { --pad: 2rem; } /* same rule, roomier variant */
Define design tokens (colors, spacing, radius) as CSS variables once, and your whole UI becomes themeable and consistent with almost no extra code.

The short version

Create CSS variables with --name on :root and read them with var(--name). Unlike Sass variables, they're live in the browser, so you can override them for dark mode, themes and component variants at runtime. Use them for your design tokens and your CSS gets shorter and more flexible.

This site's entire theme, colors, spacing, radii, is built on CSS variables, which is how dark styling and accents stay consistent everywhere.

Frequently asked questions

How do I create a CSS variable?+

Declare it with two dashes, usually on :root so it's global: :root { --accent: #38bdf8; }. Then use it anywhere with the var() function: color: var(--accent). Changing the variable's value updates every element that uses it.

What's the difference between CSS variables and Sass variables?+

Sass variables are compiled away before the browser sees them, so they're static. CSS variables (custom properties) are live in the browser and can change at runtime via JavaScript, media queries or a class. That live nature makes CSS variables ideal for theming and dark mode.

How do I use CSS variables for dark mode?+

Define your colors as CSS variables on :root, then override those same variables under a dark-mode selector or a prefers-color-scheme: dark media query. Because your styles reference the variables, only the variable values change, and the whole UI switches themes.

Can CSS variables have fallback values?+

Yes. var() accepts a second argument used when the variable isn't defined: color: var(--text-color, #333). This is useful for components that might be used outside your theme, or to provide a safe default while a variable loads.

Can I change a CSS variable for just one component?+

Yes. CSS variables cascade, so you can redefine a variable on a specific element to affect only that element and its children. For example, set --pad on a .card, then override it on .card.spacious to create a roomier variant using the same rule.

Want this done for your site?

I build fast, SEO-ready sites and rank them on Google and AI search.