🎛️ CSS Advanced

Custom Properties (Variables)

⏱ 1 hr2 topicsLive playground
🎯 By the end: You can define CSS custom properties, reuse them with var(), set global values on :root, and see why they make theming and dark mode easy.

Imagine your brand orange appears in 40 places across your stylesheet, and the boss asks for a slightly different orange. Find-and-replace 40 times? No. With CSS custom properties — often just called variables — you define that colour once and reuse it everywhere. Change it in one place, and all 40 update. This is how real design systems stay consistent.

1Defining and using a variable

A custom property is a name starting with two dashes (--), holding any value. You read it back with the var() function:

:root {
  --brand: #FF6B00;
  --space: 16px;
}

.button {
  background: var(--brand);
  padding: var(--space);
}

The :root selector is the whole document, so anything defined there is global — available everywhere. That's the usual home for your colours, spacing scale and fonts.

Custom properties also cascade and inherit: define one on a particular element and it applies to that element and its children — handy for theming just one section.
Define once, reuse everywhere
HTML
CSS
Live preview
What's happening: Change --brand at the top of :root from #FF6B00 to, say, #3C3489 and BOTH buttons update at once — that's the power of defining a value once and reusing it with var().
Key points
  • Define a variable with a --name and read it with var(--name).
  • Put global values (colours, spacing, fonts) on the :root selector.
  • Custom properties inherit, so you can theme a single section by redefining them on its container.

2Theming, fallbacks and dark mode

Because a variable can be redefined, you can flip an entire theme by changing a handful of values. A common pattern for dark mode:

:root {
  --bg: #ffffff;
  --text: #111111;
}
.dark {
  --bg: #111111;
  --text: #f5f5f5;
}
body {
  background: var(--bg);
  color: var(--text);
}

Add the dark class to the page and every element using var(--bg) / var(--text) switches instantly. No rewriting rules — just new values.

Fallbacks

var() takes an optional fallback for when the variable isn't set: color: var(--accent, #FF6B00) uses the orange if --accent is undefined.

This is the bridge to design systems (an Expert-level topic): a small set of named "design tokens" — colours, spacing, radii — that keep an entire product visually consistent.
Key points
  • Redefine variables (e.g. on a .dark class) to flip an entire theme at once.
  • var(--name, fallback) supplies a default when the variable isn't set.
  • A small set of named variables ('design tokens') keeps a whole product consistent.

★ Practical: a themeable card

In any playground:

  1. Define --brand, --bg and --radius on :root.
  2. Build a card that uses all three via var().
  3. Change --brand once and confirm everything using it updates.
  4. Add a var(--accent, #FF6B00) with a fallback and check it falls back when unset.

Ready to test yourself?

Take the short quiz. Score 60% or more to mark this lesson complete.

Start the quiz →

💡 Log in to save your progress and earn the certificate.