CSS Variables
CSS variables let you name a value once — like your brand colour — and reuse it everywhere. Change it in one place and the whole site updates.
On this page · 5 min · Intermediate
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Declare and use custom properties
- Provide fallback values
- Scope variables to components
- Build light and dark themes
- Read and change variables with JavaScript
Explanation#
Declare with two dashes: --brand: #2965f1;. Use with var(): color: var(--brand);.
Variables declared on :root are global. Declared on a selector, they apply only to that element and its children — this is called scoping.
var(--gap, 1rem) uses 1rem if --gap is not defined.
Theming: define colour variables on :root, then redefine them inside @media (prefers-color-scheme: dark) or a [data-theme="dark"] selector. Every rule using the variables switches automatically.
Unlike Sass variables, CSS variables are live in the browser: JavaScript can change them with element.style.setProperty("--brand", "red").
Syntax#
:root { --brand: #2965f1; --radius: 8px; }
.btn { background: var(--brand); border-radius: var(--radius); }
.card { padding: var(--space, 1rem); } /* fallback */
Code example: A themeable component#
<style>
:root {
--bg: #ffffff;
--text: #0f172a;
--brand: #2965f1;
--radius: 10px;
--space: 16px;
}
[data-theme="dark"] {
--bg: #0f172a;
--text: #e2e8f0;
--brand: #60a5fa;
}
body { background: var(--bg); color: var(--text); font-family: sans-serif; padding: var(--space); transition: background 200ms; }
.btn { background: var(--brand); color: var(--bg); border: 0; padding: 8px 16px; border-radius: var(--radius); }
.btn.danger { --brand: #dc2626; } /* scoped override */
</style>
<h2>Theme demo</h2>
<button class="btn" id="toggle">Toggle dark mode</button>
<button class="btn danger">Delete</button>
<p><label>Brand colour <input type="color" id="pick" value="#2965f1"></label></p>
<script>
toggle.onclick = () => {
const html = document.documentElement;
html.dataset.theme = html.dataset.theme === 'dark' ? 'light' : 'dark';
};
pick.oninput = e => document.documentElement.style.setProperty('--brand', e.target.value);
</script>
Clicking the toggle switches the whole page to dark colours; the Delete button stays red; the colour picker changes the brand colour live.
Step-by-step explanation#
- All colours and sizes are declared once on :root.
- [data-theme="dark"] redefines only the colour variables.
- Every rule uses var(), so switching the theme updates everything at once.
- .btn.danger overrides --brand only for that button.
- The script toggles data-theme on <html>.
- setProperty changes --brand live as you pick a colour.
Real-world use case#
Design systems store every colour, spacing, radius and font size as variables (“design tokens”), making rebrands and dark mode a matter of changing a few lines.
Common mistakes#
brand: red is an invalid property. Custom properties must start with --.
@media (min-width: var(--bp)) does not work. Variables only work in property values.
--Brand and --brand are two different variables.
Best practices#
- Put design tokens on :root
- Name by purpose (--color-danger) not by value (--red)
- Use scoped variables to create component variants
- Use variables for dark mode instead of duplicating rules
Remember this#
--name to declare, var(--name) to use.
Define once on :root, use everywhere.
Dark mode = redefine the colour variables, nothing else.
Practice exercise#
Your task: Create --primary and --spacing variables on :root and use them for a .card’s border colour and padding. Add a fallback for --spacing.
Need a hint?
Show solution
:root {
--primary: #7c3aed;
--spacing: 1.25rem;
}
.card {
border: 2px solid var(--primary);
padding: var(--spacing, 1rem);
}
Mini quiz#
How do you use the variable --main-color?
Want more? Practise all CSS MCQs · CSS interview questions
My notes#
Saved in this browser.