Custom Properties (CSS Variables)
Define Once, Use Everywhere
Custom properties are values you name and reuse. Define them on :root (the html element) and read them with var():
:root {
--bg: #0A0A14;
--surface: #111827;
--border: #1F2937;
--text: #F9FAFB;
--muted: #6B7280;
--accent: #6366F1;
--radius: 12px;
--space: 1rem;
--font-sans: 'Inter', sans-serif;
--shadow-lg: 0 20px 48px rgba(0,0,0,0.4);
}
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
}
.btn {
background: var(--accent);
}Change --accent once and every button, link, and highlight updates. This is a design token system — the foundation of maintainable CSS.
Fallbacks & Scope
color: var(--brand, #6366F1); /* second arg = fallback if undefined */Variables cascade and inherit like any property — define them on any element to scope them:
.danger-zone {
--accent: #EF4444; /* everything inside uses red as its accent */
}Theming — Dark Mode in Five Lines
Because variables can be redefined per-scope, theming is just swapping the token values:
:root {
--bg: #FFFFFF;
--text: #111827;
}
[data-theme="dark"] {
--bg: #0A0A14;
--text: #F9FAFB;
}
body {
background: var(--bg);
color: var(--text);
transition: background 0.3s, color 0.3s;
}// one line of JS to toggle
document.documentElement.dataset.theme = "dark";Components never mention colours directly — they use tokens, so themes apply everywhere automatically.
calc() — Math in CSS
.content {
/* mix units freely */
width: calc(100% - 280px);
min-height: calc(100vh - var(--nav-height));
padding: calc(var(--space) * 2);
}Variables + JavaScript
// read
getComputedStyle(document.documentElement).getPropertyValue("--accent");
// write — e.g. a brand colour picker, or following the mouse
document.documentElement.style.setProperty("--accent", "#EC4899");Because JS can set variables and CSS reacts instantly, variables are the clean bridge between dynamic data and styling — progress bars, theme pickers, cursor effects.
Practical Token Sets
- Colors: bg, surface, border, text, muted, accent (+ hover variants)
- Spacing scale: –space-1 through –space-8 (0.25rem × n)
- Radii: –radius-sm/md/lg/full
- Shadows: –shadow-sm/md/lg
Six colour tokens and a spacing scale will carry you through an entire product.