Practical color guide
Dark Mode Color Palette: Contrast, Surfaces and Accessible UI
Build a dark mode palette with layered surfaces, readable text, accessible accents and practical CSS variables.
Open related toolAvoid pure black everywhere
A useful dark interface usually combines several near-black surfaces rather than one flat #000 background. Small lightness differences can separate the page, navigation, panels and interactive controls without heavy borders.
Define surface and text roles
Start with page, raised surface and subtle surface tokens. Then define primary text, muted text and disabled text. Role-based names keep the theme maintainable when individual values change.
- --surface-page and --surface-raised
- --text-primary and --text-muted
- --border-subtle and --focus-ring
Reduce overly bright accents
A brand color that works on white can feel fluorescent on a dark background. Test a slightly lighter but less chromatic variant, then verify contrast for text, icons and focus rings.
Test every component state
Check normal, hover, active, focus and disabled states. Inputs, charts, alerts and code blocks often reveal issues that are not visible in a simple text contrast test.
Respect the user preference
Use prefers-color-scheme as a sensible default and preserve an explicit user choice. Keep the document color-scheme value aligned so native controls render consistently.
Technical references
This guide was checked against the following primary references.
Frequently asked questions
Should dark mode use pure black?
Not necessarily. Near-black surfaces often provide more comfortable hierarchy, while pure black can remain useful for specific OLED or media contexts.
Do WCAG contrast rules change in dark mode?
The contrast calculation does not change. Test the actual foreground and background values used in each state.