Light theme: the familiar default
Most interfaces historically assume a light background with dark text. In that setup:
Light theme characteristics
- Backgrounds are high lightness (near white).
- Body text is dark gray or near‑black.
- Shadows and borders help create depth.
- Strong colors appear as accents on otherwise neutral surfaces.
Light themes are generally easier for:
Where light themes excel
- Displaying large blocks of text
- Printing or exporting screenshots
- Users coming from traditional desktop apps and documents
Because this is the "default mental model", many color systems are originally designed with a light theme in mind.
Dark theme: not just inverted colors
Dark themes start with dark backgrounds and light text, but a good dark mode is more than an inverted light palette.
If you simply invert or mirror light theme colors you often get:
Pitfalls of naive inversion
- Blurry or overly bright text
- Harsh contrast that is tiring over time
- Accent colors that look neon or oversaturated
Instead, treat your dark theme as:
A better approach
- A separate, but related, color system
- Built on the same roles (primary, secondary, neutrals, semantic colors)
- With values tuned for dark surroundings
Key differences from a light theme:
Base background
- Moves from light gray/white to dark gray/near‑black.
Text
- Moves from dark gray to light gray/near‑white.
Accent colors
- Saturation and lightness are adjusted to avoid glow and eye strain.
Contrast in dark mode
Contrast in dark mode feels different, even when the numeric ratio is the same.
Technically, WCAG contrast rules apply the same way:
But perceptually:
Perception in dark mode
- Pure white on pure black is very harsh.
- Slightly softer combinations (off‑white text on deep gray) are more comfortable while still meeting contrast requirements.
Practical advice:
Dark mode contrast guidelines
- Avoid absolute black and absolute white in most UI elements.
- Use very dark grays for backgrounds —
#05050a,#101012, etc. - Use off‑white for text —
#e5e7eb,#f3f4f6, etc. - Keep line height generous and font weights moderate; thin white text on dark backgrounds is harder to read.
When designing your dark palette, constantly test real components — buttons, list items, cards — not just isolated swatches.
Saturation and the “neon effect”
On dark backgrounds, saturated colors appear much stronger than in light themes. A button color that feels balanced on white can look like a glowing sticker on near‑black.
Common issues
- Primary buttons become too loud and distracting.
- Large blocks of saturated color feel heavy and tiring.
- Semantic colors (especially red) look aggressive.
Techniques to handle this:
Handling saturation in dark mode
- Slightly reduce chroma/saturation for accent colors in dark mode.
- Use lighter tints of the same hue for large surfaces, keeping the more saturated versions for small icons and text.
- Limit large surfaces in pure brand colors — rely more on dark neutrals for backgrounds.
Perceptual color models (like OKLCH) make this easier: you can keep lightness similar but dial down chroma for dark mode versions of a color.
Neutrals and depth in dark mode
Light themes use white page backgrounds, light gray cards, and shadows for elevation. In dark mode you have to invert that logic while keeping enough layering.
Light theme
- White page background
- Light gray cards and panels
- Drop shadows for elevation
- Dark text and borders
Dark theme
- Deep near‑black background
- Slightly lighter grays for cards
- Subtle borders or inner shadows
- Light text and faint overlays
Important
- Don't rely solely on shadows for depth — they're hard to see on dark backgrounds.
- Use contrast in lightness between layers (background vs card vs overlay) plus subtle borders.
Radix Colors and Material both define rich neutral scales specifically tuned for dark surfaces, which can be a good starting point.
Primary, semantic and brand colors in dark themes
You usually want the same semantic meaning in both themes — green for success, red for error, yellow/orange for warning, blue for information. But the exact values often differ.
Dark theme versions may have:
Typical adjustments for dark mode
- Slightly lower chroma
- Slightly higher lightness (to stand out from dark background)
- Adjusted hue to avoid weird halos or color bleed
An example mapping strategy:
How Material, Tailwind and Radix handle light/dark themes
Material Design
- Provides separate light and dark theme guidance.
- Uses a tonal palette system — each base color generates tones from 0–100.
- Different tone values are used for surfaces, text and accents in light vs dark.
- In dark mode, elevation is suggested through lighter overlays rather than heavy shadows.
Tailwind CSS
- Provides a unified scale per hue (50–900) with a dark: variant for different classes.
- Expects you to choose appropriate shades per theme — e.g. gray-50 background in light, gray-950 in dark.
- Primary colors shift to lighter shade numbers in dark mode — e.g. light: blue-600 → dark: blue-400.
- Newer versions and community presets use perceptual color spaces (like OKLCH) for smoother mapping.
Radix Colors
- Explicitly ships paired light and dark palettes for each color (e.g. blue and blueDark).
- Both are perceptually consistent and accessible out of the box.
- The dark palette has carefully adjusted chroma and lightness per step.
- Includes alpha versions and semantic scales — excellent for themeable React UIs where light/dark switching should "just work".
Designing your own light & dark pair
When building your own dual theme, a practical workflow is:
- 1
Define roles first. Decide on roles like background, surface, text, border, primary, secondary, success, warning, error, info.
- 2
Design the light theme. Use collections like Tailwind, Material, Open Color or Radix as starting points. Focus on comfortable reading, clear hierarchy and accessible contrast.
- 3
Create a dark theme as a sibling, not an inversion. Pick dark neutrals for background and surface. Choose lighter, slightly less saturated versions of your primary and semantic colors. Tune link and button states so they stand out without glowing.
- 4
Test real components. Typography, buttons, inputs, cards, modals, status banners and toasts — side‑by‑side in light and dark.
- 5
Codify as tokens. color.bg.default.light / .dark, color.text.primary.light / .dark, color.primary.default.light / .dark, etc.
Colorr's role is to give you named, well‑structured color collections — Tailwind, Material, Radix and others — as building blocks. From those building blocks you can craft paired light and dark themes that feel related, readable and pleasant to use, without falling into the trap of simple inversion.