Dark Mode Design: A Practical Guide

Dark mode is no longer optional. Most modern operating systems offer it, most users prefer it for at least some contexts, and apps that ship only a light theme look dated. But naive dark mode — inverted colors, harsh contrast, broken elevation — is often worse than no dark mode at all. This guide covers what makes dark mode work.

The Core Decisions

ElementLight modeDark mode
Surface base#FFFFFF#121212 or similar near-black
Body text#111 or #222rgba(255,255,255,0.87)
Secondary textrgba(0,0,0,0.6)rgba(255,255,255,0.6)
ElevationShadowsLighter background tints
Brand colorSaturatedDesaturate 15-30%
BordersLight graySubtle lighter tint

The Pitfalls

  • Pure black backgrounds. Harsh contrast and OLED smearing during scroll. Stick to near-black.
  • Pure white text. Vibrates and tires eyes. Use slightly muted white.
  • Highly saturated brand colors. Look neon and aggressive on dark. Desaturate.
  • Drop shadows for elevation. Mostly invisible on dark surfaces. Use background lightness.
  • Same image assets. Photos and screenshots designed for light backgrounds often have white edges or shadow halos that show on dark. Provide dark variants where it matters.
  • Inverted colors only. Algorithmic inversion produces ugly, low-contrast palettes. Hand-design dark colors.

The Implementation Pattern

:root {
  --bg-surface: #ffffff;
  --text-primary: #111111;
  --brand: oklch(0.55 0.18 270);
}
:root[data-theme="dark"] {
  --bg-surface: #121212;
  --text-primary: rgba(255,255,255,0.87);
  --brand: oklch(0.7 0.14 270);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg-surface: #121212;
    --text-primary: rgba(255,255,255,0.87);
    --brand: oklch(0.7 0.14 270);
  }
}

Testing Checklist

  • Run a contrast audit on the dark palette specifically — light-mode passes don't transfer.
  • Check all interactive states (hover, focus, active, disabled) in both modes.
  • Test images, illustrations, and screenshots in dark — flag the ones that look wrong.
  • Test the theme toggle in both directions, and respect prefers-color-scheme as default.

Try It Yourself

Test colors and palettes for dark mode with DesignKit's color tools.

Color Palette Extractor →

Frequently Asked Questions

It reverses contrast assumptions, breaks shadow-based elevation, saturates color differently, and exposes hidden a11y issues.
Rarely. Near-black (#121212) reduces harshness and OLED smearing.
Lighter background tints replace shadows. Higher elevation = lighter surface.
Adjust, don't redesign. Desaturate brand colors; use soft white for text.
CSS custom properties scoped to a theme attribute; respect prefers-color-scheme; manual toggle for override.