The Problem with Most Dark Modes
Most dark modes are just... inverted light modes. White becomes black, black becomes white, and everything looks harsh and uncomfortable. A good dark mode requires completely rethinking your color system.
The Cardinal Sins of Dark Mode
- Pure black backgrounds —
#000000creates too much contrast with white text - Desaturated colors — Colors that look great on white look neon on dark backgrounds
- Ignoring elevation — Surfaces need subtle differentiation in dark mode too
- Forgetting about shadows — Shadows don't work on dark backgrounds
Building a Proper Dark Palette
Here's the approach I use:
:root {
/* Light - warm and inviting */
--background: #fafafa;
--foreground: #0a0a0a;
--surface: #f4f4f5;
--border: #e4e4e7;
--accent: #ec4899;
}
.dark {
/* Dark - not pure black, slightly warm */
--background: #050505;
--foreground: #fafafa;
--surface: #18181b;
--border: #27272a;
--accent: #f472b6;
}
Notice the accent color shifts slightly between modes. On dark backgrounds, a lighter, softer pink reads better than the full saturation version.
The Elevation System
In dark mode, elevation is communicated through subtle lightening:
.surface-base { background: var(--background); }
.surface-raised { background: var(--surface); }
.surface-overlay { background: #27272a; }
Each level adds just enough contrast to create depth without being obvious.
Text and Readability
Contrast Ratios
WCAG guidelines still apply in dark mode. But the feeling of good contrast is different. Aim for:
- Headings: Higher contrast — closer to white
- Body text: Medium contrast — slightly dimmed
- Muted text: Lower contrast — but still readable
- Disabled text: Low contrast — clearly inactive
Motion and Atmosphere
Dark mode is an opportunity to add subtle atmospheric effects:
- Grain overlays — Add texture to prevent banding on dark gradients
- Glow effects — Accent colors can emit subtle light
- Transparency — Frosted glass effects look stunning on dark backgrounds
Conclusion
A dark mode worth shipping takes as much design effort as the light mode. Don't treat it as an afterthought. Your users who prefer dark mode deserve the same level of care and intentionality.
Dark mode isn't just a color scheme — it's an atmosphere.
Building with Next.js 16: What's New
Exploring the latest features in Next.js 16, including the new compiler, improved caching, and breaking changes you should know about.
The Art of Clean Code: Lessons from Real Projects
Practical insights on writing maintainable code, drawn from years of experience working on production systems and open source projects.
Rhythm Games and Programming: A Surprising Connection
How playing osu!mania and other rhythm games shaped my approach to coding, problem-solving, and the pursuit of mastery.