DevPath · Learn to code ESPTEN

Modern CSS, accessibility and architecture

Custom properties: CSS variables

Native variables in CSS

You made it to the last Web module, and we're opening it with one of those features that just feels good: CSS finally has real variables.

Custom properties (or CSS variables) are reusable values you declare with a name starting with two dashes -- and read with the var() function. Unlike the variables of a preprocessor like Sass, they are dynamic: they live in the DOM, they cascade and they are inherited. That one difference changes everything, as you'll see.

Declaring in :root

The usual place to define global variables is the pseudo-selector :root, which represents the document (equivalent to <html> but with higher specificity). This way they are available across the whole page.

:root {
  --primary-color: #2563eb;
  --text-color: #1f2937;
  --space: 16px;
  --radius: 8px;
}

Using with var()

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

var() accepts a fallback value in case the variable is not defined:

.notice {
  color: var(--notice-color, #b91c1c); /* uses #b91c1c if --notice-color does not exist */
}

Why they matter: theming and maintenance

Here's the gold. Without variables, changing your brand blue meant find-and-replace thirty times, praying you didn't miss one. With variables:

:root { --background: white; --text: #111; }

[data-theme="dark"] {
  --background: #0f172a;
  --text: #e2e8f0;
}

body { background: var(--background); color: var(--text); }

Changing data-theme on <html> rewrites the variables and, with them, the whole appearance. That is the basis of a maintainable dark mode: one attribute, a thousand styles switching at once. The good kind of magic.

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
Modern CSS: clamp(), aspect-ratio, :has() and more →