Building a Theme System with CSS Custom Properties
CSS Custom Properties (also known as CSS Variables) provide a powerful way to build maintainable theme systems. Unlike preprocessor variables, they’re live in the browser and can be changed dynamically.
Defining Your Color Palette
Start by defining your base colors on the :root element:
:root {
--color-bg-primary: #0a0a0a;
--color-text-primary: #fafafa;
--color-accent: #00ff88;
}
Light Mode Overrides
Use a data attribute to switch themes without JavaScript complexity:
[data-theme="light"] {
--color-bg-primary: #fafafa;
--color-text-primary: #0a0a0a;
--color-accent: #00aa55;
}
Fluid Typography
CSS custom properties work beautifully with clamp() for fluid typography:
:root {
--text-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
--text-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem);
}
Benefits Over Preprocessors
- Live updates - Change values at runtime
- Cascade aware - Respect specificity and inheritance
- JavaScript integration - Read and write from JS
- No build step - Work directly in the browser
Implementing Theme Toggle
A simple theme toggle can be just a few lines:
const toggle = document.getElementById('theme-toggle');
toggle.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
CSS Custom Properties have transformed how we build design systems. They’re now my go-to approach for any theming needs.