CSS Variables for Theming
Declare custom properties with --, use var(), override them in nested scopes, and implement a light/dark theme toggle.
CSS Variables for Theming is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Are CSS Custom Properties?
CSS custom properties (CSS variables) store values that can be reused throughout a stylesheet. Declared with --name: value and accessed with var(--name). Unlike preprocessor variables (Sass), they're dynamic — you can update them with JavaScript.
Declaring Custom Properties
Declare properties on :root to make them globally available. You can also declare them on any element to scope them to that element's subtree.
:root {
--color-primary: #3182ce;
--color-bg: #f7fafc;
--color-text: #1a202c;
--spacing-md: 16px;
--border-radius: 8px;
--font-sans: 'Inter', system-ui, sans-serif;
}Using Custom Properties
Reference a variable with var(--name). Include a fallback as the second argument: var(--color-primary, #3182ce). The fallback is used if the variable isn't defined.
.card {
background: var(--color-bg);
color: var(--color-text);
padding: var(--spacing-md);
border-radius: var(--border-radius);
}
.btn {
background: var(--color-primary, blue); /* fallback */
}The Cascade: Scoped Variables
Custom properties cascade and inherit. If you redefine a variable on a child element, it overrides the parent's value for that element and all its descendants.
:root { --accent: blue; }
.card { color: var(--accent); } /* blue */
.special-section {
--accent: green; /* override for this subtree */
}
.special-section .card { color: var(--accent); } /* green */Dark Mode with CSS Variables
The cleanest dark mode pattern: define light and dark colour palettes as CSS variables. Toggle a class or use the prefers-color-scheme media query to switch. No need to override individual colour properties.
:root {
--bg: #ffffff;
--text: #1a202c;
--card-bg: #f7fafc;
}
[data-theme='dark'], @media (prefers-color-scheme: dark) {
:root {
--bg: #1a202c;
--text: #f7fafc;
--card-bg: #2d3748;
}
}
body { background: var(--bg); color: var(--text); }Toggling Dark Mode with JavaScript
Add a toggle button that switches a data attribute or class on the root element. CSS variables handle the rest — one line of JavaScript, no individual style overrides.
const btn = document.querySelector('#theme-toggle');
btn.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
document.documentElement.setAttribute(
'data-theme',
current === 'dark' ? 'light' : 'dark'
);
});Updating Variables with JavaScript
element.style.setProperty('--name', value) updates a custom property inline. Removing it with removeProperty restores the cascade value. This enables dynamic themes and animated values.
// Dynamically set a CSS variable from JS:
document.documentElement.style.setProperty('--primary-hue', '220');
// Based on input:
const hue = document.querySelector('#hue-slider');
hue.addEventListener('input', () => {
document.documentElement.style.setProperty('--primary-hue', hue.value);
});Design Tokens as CSS Variables
Define all design decisions — colour palette, spacing scale, type scale — as CSS variables. This creates a single source of truth that components consume. Changing a token propagates everywhere instantly.
:root {
/* Colour scale */
--blue-50: #ebf8ff;
--blue-100: #bee3f8;
--blue-500: #3182ce;
--blue-900: #1a365d;
/* Spacing scale */
--space-1: 4px;
--space-2: 8px;
--space-4: 16px;
--space-8: 32px;
}Using Variables in calc()
CSS variables work inside calc(), enabling responsive calculations based on token values.
:root { --header-height: 64px; }
.content {
/* Leave room for fixed header */
padding-top: calc(var(--header-height) + 24px);
min-height: calc(100vh - var(--header-height));
}Browser Support
CSS custom properties are supported in all modern browsers (since 2016 for major browsers). No need for a preprocessor for this feature. Fallback for very old browsers: provide a static value before the var().
.btn {
background: blue; /* IE fallback */
background: var(--color-primary); /* modern browsers */
}Custom Properties vs Sass Variables
Sass variables are compiled to static values. CSS custom properties exist at runtime, are dynamic, can be changed with JavaScript, and cascade through the DOM. Use CSS variables for theming; Sass variables for build-time constants.
Quick Check
How do you read and update a CSS custom property from JavaScript?
Recap: CSS Custom Properties
Declare with -- on :root for global scope. Use with var(). Scoped variables cascade to descendants. Dark mode: redefine colour tokens in a media query or data attribute. Update from JavaScript with style.setProperty(). Design tokens as variables = one source of truth.
Frequently asked questions
Is the “CSS Variables for Theming” lesson free?
Yes — the full text of “CSS Variables for Theming” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “CSS Variables for Theming”?
Declare custom properties with --, use var(), override them in nested scopes, and implement a light/dark theme toggle. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “CSS Variables for Theming” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.