Dark Mode Done Right: Design, Code and Brand Considerations

Dark mode is a second brand surface, not an inverted stylesheet. How to build it with prefers-color-scheme and colour tokens, keep contrast accessible, and stop your logo vanishing on dark backgrounds.

Do users actually want dark mode?

Dark interfaces stopped being a developer niche years ago. Every major operating system ships a system-wide dark scheme, many phones switch automatically at sunset, and surveys consistently find that a large share of users keep dark mode on for some or all of the day. The preference skews even stronger among developers, gamers and heavy evening browsers.

For a business website, the question is less "should we build a dark theme?" and more "should we ignore a preference the visitor has already stated?" The prefers-color-scheme signal arrives with every visit. A site that blasts pure white at someone browsing in bed at 11pm is ignoring a politely made request. That said, dark mode is optional polish rather than an obligation: if your budget covers only one theme, a well-contrasted light theme serves everyone acceptably.

The mechanics: three features do most of the work

Modern CSS keeps the plumbing short:

  • The prefers-color-scheme media query lets you supply alternative styles when the visitor's OS is set to dark.
  • color-scheme: light dark on the root element tells the browser to render form controls, scrollbars and default backgrounds appropriately in each mode, for free.
  • The light-dark() CSS function, now supported in all major browsers, sets both values in one declaration: color: light-dark(#1a1a1a, #e8e8e8).

Also add <meta name="color-scheme" content="light dark"> so the browser knows before the stylesheet loads, which prevents a white flash on dark-mode devices while the page is loading.

Need a hand with this?

Our team delivers UI/UX Design for UK businesses — with a free initial consultation, transparent fixed quotes and no lock-in contracts. Tell us what you're working on →

Tokens first, themes second

The dark-mode projects that go wrong are the ones that scatter hex codes through the CSS and then try to override each one individually. The fix is a semantic token layer: variables named for their role rather than their colour.

  • Literal naming (avoid): --blue-600 and --grey-100 referenced directly inside components.
  • Semantic naming (use): --surface, --surface-raised, --text-primary, --text-muted, --accent, --border.
  • Components reference only semantic tokens; the dark theme then redefines those tokens in one block, under the media query or a [data-theme="dark"] attribute.

Done this way, dark mode is a fifteen-line token remap. Done the other way, it is a month of whack-a-mole and a stylesheet nobody trusts.

Contrast and colour: where dark themes go wrong

Inverting colours is not designing a dark theme. The common failures are predictable and avoidable:

  • Pure black backgrounds with pure white text create a harsh halation effect that makes text shimmer for many readers. Use a dark grey (around #121212 is a common choice) with off-white text instead.
  • Saturated brand colours that look crisp on white tend to vibrate on dark surfaces. Desaturate and lighten your accents slightly for the dark palette.
  • WCAG contrast minimums (4.5:1 for body text) apply in both themes, and dark themes fail them surprisingly often, especially on muted secondary text.
  • Shadows barely register on dark surfaces, so signal elevation by making raised surfaces slightly lighter rather than relying on drop shadows.

Logos, images and the brand question

Assets need as much attention as CSS. A dark logo on a transparent background disappears entirely in dark mode, which is the single most common dark-mode bug on small-business sites.

  • Ship logo variants: an SVG using currentColor adapts automatically; otherwise prepare a light-on-transparent version and swap it using the picture element with a prefers-color-scheme media attribute.
  • Dim large photographs slightly (filter: brightness(0.85)) so they do not glow against dark surroundings.
  • Check illustrations, charts and embedded diagrams: hard-coded white backgrounds turn into glowing rectangles.
  • Decide the brand position deliberately. Dark mode is a second brand surface, and your palette, photography and tone should feel intentional there rather than accidentally inverted.

Key Takeaway

Treat dark mode as a second brand surface, not an inverted stylesheet. Build semantic colour tokens, honour prefers-color-scheme by default, and offer a three-state toggle persisted in localStorage with an inline head script to prevent a flash of the wrong theme. Use dark grey rather than pure black, desaturate accent colours, keep WCAG contrast in both themes, and prepare logo and image variants before launch so nothing vanishes on dark backgrounds.

Shipping it: toggle, persistence, no flash

The last mile is behaviour, and it is where good implementations separate from annoying ones:

  • Default to the OS preference; that respects the choice most users have already made.
  • Offer a three-state toggle (light, dark, system) rather than a binary switch, and persist the choice in localStorage.
  • Apply the stored choice with a tiny inline script in the head, before the first paint, or returning visitors get a flash of the wrong theme on every page load.
  • Test both themes in QA on every release; regressions in dark mode are invisible to teams who work in light mode all day.
  • Track toggle usage in analytics so future design decisions rest on your audience's actual behaviour.

Handled as a token system with proper assets, dark mode is a modest project with a long shelf life. If you would like your site's palette and components rebuilt to support it cleanly, our team can help.

Work With Us

Need Help With Your Digital Strategy?

Our team of experts is ready to help. Get a free consultation and tailored proposal.