Dark Mode Done Right

Dark mode isn’t just “invert the colors.” Done poorly, it’s harsh and hard to read. Done well, it feels natural and reduces eye strain.

The principles

A few things I’ve learned from building dark interfaces:

Don’t use pure black

#000000 on screens creates too much contrast with white text. Instead, use a very dark teal — something like #091c1e — which is easier on the eyes while still feeling deep and immersive.

Reduce contrast for body text

White text (#ffffff) on a dark background is jarring. Aim for an off-white like #f6fff5 for headings, and use reduced opacity for body text:

RoleColorHex
HeadingsNear white#f6fff5
Body80% opacityrgba(246,255,245,0.8)
MutedWarm gray#978e81

Use warm accents

In dark interfaces, warm accent colors feel more natural than cold ones. An orange like #f6833b creates energy without overwhelming the reading experience.

The technical bits

CSS custom properties make theming straightforward:

:root {
  --background: #091c1e;
  --foreground: #f6fff5;
  --accent: #f6833b;
}

This keeps your design tokens in one place. Change a variable, and the entire site updates.

Typography matters most

In dark mode, font rendering behaves differently. Lighter text on dark backgrounds appears thicker due to subpixel antialiasing. Counter this with:

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

This produces thinner, crisper text that reads much better on dark surfaces.