Dark Mode Done Right with CSS Custom Properties
The Problem with Dark Mode
Most dark mode implementations are an afterthought. Colors are inverted crudely, contrast is wrong, and the transition is jarring. We can do better.
CSS Custom Properties to the Rescue
The key to a great dark mode is design tokens. Define your entire color palette as CSS custom properties:
:root {
--bg-primary: #0a0a1a;
--bg-secondary: #0f0f2e;
--text-primary: #e2e8f0;
--text-secondary: #94a3b8;
--accent: #06b6d4;
}
Glassmorphism in Dark Mode
Dark mode is the perfect canvas for glassmorphism effects. The frosted glass look works best against dark backgrounds:
.glass {
background: rgba(255, 255, 255, 0.04);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 16px;
}
The secret is in the numbers:
- Background opacity: Keep it between
0.02and0.08for subtlety - Blur radius:
16pxto24pxgives the best frosted effect - Border: A near-invisible border adds depth without being distracting
Smooth Transitions
When toggling themes, animate the change:
body {
transition: background-color 0.3s ease,
color 0.3s ease;
}
Respecting User Preferences
Always check the system preference first:
@media (prefers-color-scheme: dark) {
:root {
/* Dark mode tokens */
}
}
This ensures your site respects the user’s OS-level preference out of the box.
Key Takeaways
- Use CSS custom properties for all colors
- Design dark mode first, not as an afterthought
- Test contrast ratios — WCAG AA minimum
- Animate theme transitions smoothly
- Respect
prefers-color-scheme