Designing dark mode properly
Dark mode is not an inversion
Flipping every colour produces muddy, harsh results. A good dark theme is designed on its own terms: surfaces, text, accents and images each get deliberate values. Many people choose dark mode for comfort in low light, so the goal is a calm, readable screen.
Soft surfaces and text
- Avoid pure black backgrounds. A very dark grey, such as #121212, feels softer and leaves room to show depth.
- Avoid pure white text. Off-white, such as #ececec, reduces glare against dark surfaces.
- Show elevation with lighter surfaces. Shadows are hard to see on dark backgrounds, so raised layers such as cards and dialogs use slightly lighter fills.
A simple elevation ladder keeps layers consistent: the page background is the darkest, cards sit one step lighter, and menus or dialogs one step lighter again. Limit the ladder to three or four levels so each remains distinguishable.
Accents, contrast, images and pitfalls
Saturated accents that look fine on white can vibrate on dark surfaces. Lighten or slightly desaturate them. Then re-check contrast: body text still needs 4.5:1 and UI components 3:1 under WCAG, and passing in light mode proves nothing about dark mode.
Handle images deliberately. Photos usually work as they are, but a very bright image can glare; logos and illustrations with white backgrounds may need a transparent or alternate version.
Dark themes tend to fail in a few predictable places. Check these before shipping:
- Thin grey text on a dark surface often falls below 4.5:1. Measure it.
- Borders that were visible on white may disappear. Use a slightly lighter border colour.
- Hard-coded colours inside components stay light when the theme changes. Replace them with tokens.
- Large areas of bright white, such as an embedded document, can feel jarring in the dark theme.
Test dark mode in a dim room as well as on a bright screen, with real content.
Implement with tokens and user choice
Build both themes on semantic colour tokens, so components never contain raw colour values. Respect the system setting with the <code>prefers-color-scheme</code> media query, and also offer a manual switch, because some people want a different theme from their device.
- Define dark values for every semantic token.
- Use lighter fills for higher layers.
- Adjust accents and re-measure contrast.
- Review images, logos and illustrations.
- Add a manual switch and remember the choice.
Document the dark values next to the light ones in the design system. A table with each token, its light value, its dark value and the measured contrast gives developers and reviewers one place to check.
Sources
- MDN Web Docs. prefers-color-scheme. https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
- W3C. Web Content Accessibility Guidelines (WCAG) 2.2. https://www.w3.org/TR/WCAG22/
This guide was drafted with AI assistance from public standards and references. For the exact wording of a standard, use the sources listed above.