Skip to main content
Frontend is a free bonus on CodeMentor AI — the main product is Python. Register to save your progress and unlock all 290 Frontend lessons + 1,000+ Python lessons.Sign up — free
🎨 CSS as a design system·Module B1 · Lesson 9
TaskDefine CSS variables on :root: --primary (#3B82F6), --bg (#ffffff), --radius (12px), --pad (16px). Use them on .card: background var(--bg), border-radius var(--radius), padding var(--pad). On .cta: background var(--primary), color white, border-radius var(--radius), padding var(--pad).

Custom properties (CSS variables) — the new constants

100 XP8 minFREE
Theory

CSS variables, finally good in 2026

:root {
  --color-primary: #3B82F6;
  --color-bg: #ffffff;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --radius: 12px;
}

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

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

Define once on :root (so they're available everywhere). Use var(--name) anywhere.

Why this matters

  1. Single source of truth for design tokens. Change --color-primary once → every button/link/badge updates.
  2. Cascade-aware. A custom property defined on :root inherits down. Override it on a specific element and ALL its descendants get the new value (the basis of dark mode).
  3. JS-controllable. document.documentElement.style.setProperty('--color-primary', '#22C55E') swaps the value at runtime — instant theme change.

Default values

.card {
  border: var(--card-border, 1px solid #ccc);    /* fallback if --card-border isn't set */
}

The second arg is a fallback. Use sparingly — too many defaults defeat the "single source of truth" win.

Custom property scope

Define on :root → global. Define on a specific selector → scoped to that subtree:

:root { --bg: white; }
.dark { --bg: #0D1117; }     /* anything inside .dark sees --bg as dark */
body { background: var(--bg); }

Naming convention

The community converges on --{category}-{name}:

--color-primary
--color-text
--color-bg
--space-sm / --space-md / --space-lg
--font-display / --font-body / --font-mono
--shadow-sm / --shadow-md
--radius-sm / --radius-md

Predictable, autocompletes well, makes design system handoff easier.

2 tabs
Live preview
PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.