Design tokens are the named, reusable values behind a UI — learn how naming colors, spacing, and typography as tokens (often CSS custom properties) makes a product consistent and themeable, including dark mode.
Why: a design token is a named value standing in for a raw one — color-primary instead of #2563eb, space-4 instead of 16px. Naming the decision means you set it once and reference it everywhere; change the token and the whole product updates. Note: on the web, tokens are most often CSS custom properties (the --variables), so design and code share the same names.
:root {
/* Color tokens */
--color-primary: #2563eb;
--color-text: #1a1a2e;
/* Spacing scale (a consistent rhythm, not random pixels) */
--space-2: 8px;
--space-4: 16px;
}
/* Components reference tokens, never raw values */
.button {
background: var(--color-primary);
padding: var(--space-2) var(--space-4);
}Why: name colors by role, not by hue — --color-danger, not --color-red — so the meaning survives a rebrand and components read clearly. And every text/background token pair must meet WCAG contrast (4.5:1 for normal text), or the prettiest palette is unusable. Note: "functional" naming is what lets you swap themes without renaming anything.
:root {
/* ❌ Names tied to appearance break when the brand changes */
--blue: #2563eb;
/* ✅ Names tied to ROLE survive a rebrand and read clearly */
--color-primary: #2563eb; /* actions, links */
--color-danger: #dc2626; /* destructive actions, errors */
--color-text: #1a1a2e; /* must hit 4.5:1 on the background */
}Why: consistency comes from scales — a fixed set of steps instead of arbitrary values. A spacing scale (4, 8, 16, 24…) gives even rhythm; a type scale gives clear hierarchy; defined breakpoints keep responsive layouts predictable. Note: picking from a small scale is faster to design and far more consistent than free-typing pixel values.
:root {
/* Type scale — sizes step up by ratio, not at random */
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.25rem;
--text-xl: 1.5rem;
/* Breakpoints for responsive layout */
--bp-tablet: 768px;
--bp-desktop: 1024px;
}Why: because components reference tokens (never raw values), you get theming almost for free — redefine the tokens in a different context and everything re-skins itself. Dark mode is just a second set of values for the same token names. Note: this is the real payoff of tokens — one switch, the whole UI follows.
:root {
--color-bg: #ffffff;
--color-text: #1a1a2e;
}
/* Same token names, new values when the user prefers dark */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #1a1a2e;
--color-text: #f5f5f5;
}
}
/* Components didn't change at all — they just follow the tokens */
body { background: var(--color-bg); color: var(--color-text); }