Stockio

Dark Mode Color Palette: Surfaces, Elevation and Accents

Build a dark palette around clear surface steps, readable foreground pairs and restrained accents, then test it against real product screens rather than isolated swatches.

By Jonah Weiss

Design Systems Lead ·

On this page

A usable dark palette is not a light palette with its values reversed. It needs a deliberate relationship between the page, raised surfaces, text and action colours. Start with a dense screen containing navigation, a form, a card and a dialog: that composition exposes weak colour relationships faster than a row of attractive swatches.

Establish the background and foreground pairs

Choose a base surface first, then test its intended foreground in the contrast checker. Enter both colours, inspect the ratio and repeat for secondary text. Record pairs rather than approving individual colours. A foreground that works on the page may fail on a brighter card or a tinted selected row.

As a starting experiment, use a near-black blue-grey such as #11151C rather than assuming pure black is mandatory. Add a pale foreground such as #E8EDF4, then judge the combination at actual paragraph size. These are candidate values, not a pre-certified palette. Pure black remains legitimate when the product's visual language or display context calls for it.

Keep the number of neutral roles small. Most interfaces initially need a canvas, a default surface, a raised surface, a primary foreground and a secondary foreground. Introduce additional roles only when a real component needs them. The earlier dark mode psychology guide provides context; this workflow concentrates on implementing and checking the palette.

Make elevation visible without depending on shadows

In a dark interface, a black shadow can disappear against the surrounding page. Give surface elevation a tonal signal as well. Try #11151C for the canvas, #191F29 for cards and #242D3A for a dialog. The precise differences should be tuned together, not generated by adding the same RGB amount indefinitely.

Keep the hue direction consistent so raised surfaces do not suddenly look purple or green. A low-chroma cool neutral often sits comfortably beside blue accents, but warm brands may benefit from warmer greys. Inspect large areas: a tint barely visible in a swatch becomes obvious across a full dashboard.

Use a border when adjacent surfaces need a stronger edge without another elevation step. A slightly lighter outline can separate an input from a panel while preserving the panel's hierarchy. For related depth choices, compare the soft shadow techniques guide, but avoid making shadow darkness the only distinction between layers.

Establish a rule for stacked overlays. If each nested panel becomes substantially lighter, a complex dialog can turn into a light-mode island. Cap the number of surface tiers and use spacing, borders or layout for further grouping. Reserve the brightest neutral surface for a genuinely important layer, not every interactive element.

Tune accents for dark surroundings

A saturated brand colour often appears more intense against a dark background. Instead of pasting the marketing hex value everywhere, create a dark-theme accent with a useful foreground partner. A lighter blue may work well for links, while a deeper blue may be better as a filled button with pale text.

Treat link colour and button fill as separate jobs. One must distinguish a short text label from surrounding prose; the other must support a readable label inside a filled shape. They can share a hue without sharing a value. Check each actual pairing rather than requiring one magic brand swatch to solve every situation.

Give destructive, warning and success colours independent treatment. A vivid red should not become the universal highlight merely because it belongs to the brand. Preserve semantic separation through labels and icons, and keep ordinary accents from competing with critical messages. The W3C guidance on use of colour explains why colour alone cannot carry meaning.

For tinted callouts, begin with a quiet background and a clearer foreground, not a bright solid rectangle. Test the callout inside both the default and raised surfaces. Translucent tints can shift substantially between them, so an opaque token may offer a more predictable result.

Encode roles rather than component guesses

Put the chosen relationships into semantic variables. Components should request a surface or foreground role instead of selecting a grey by eye. This makes the dark palette coherent and gives later changes a clear scope.

:root {
color-scheme: dark;
--canvas: #11151c;
--surface: #191f29;
--surface-raised: #242d3a;
--text: #e8edf4;
--text-secondary: #b8c3d1;
--accent-fill: #2458b8;
--on-accent: #ffffff;
}

body { background: var(--canvas); color: var(--text); }
.card { background: var(--surface); }
.dialog { background: var(--surface-raised); }
.primary-action {
background: var(--accent-fill);
color: var(--on-accent);
}

The declaration of color-scheme helps the browser choose appropriate built-in controls and default rendering; it does not automatically redesign authored colours. Review MDN's color-scheme documentation before assuming native inputs and custom controls will match.

Keep foreground partners explicit. A token named on-accent is easier to audit than an unconditional white label scattered through component styles. If an accent changes to a pale yellow later, that explicit relationship makes the required dark label much easier to identify.

Review the palette in demanding conditions

Create a comparison screen with body copy, muted timestamps, placeholders, selected rows, inline links and validation messages. Include a dialog over the page and a disabled action beside an enabled action. Review the screen at the actual zoom level and component sizes people will use, not only in an enlarged design canvas.

Check text pairs against the applicable requirements described in W3C's contrast minimum guidance. Ordinary text generally needs 4.5:1, while qualifying large text needs 3:1. Secondary content is still content; calling a token muted does not remove its readability requirements.

Then inspect the palette on more than one display and in both bright and dim rooms. This is a practical visual review, not a substitute for measurement. Pay particular attention to near-black distinctions that disappear on some screens and pale fine text that feels harsh in a dark room.

Document adjustments as relationships: raised surfaces need more separation, secondary text needs more contrast, or accent fills need less saturation. That language prevents random local fixes. Keep a small screenshot set so future palette changes can be reviewed against the same content and states.

Key takeaways

  • Build foreground-background pairs, not isolated approved swatches.
  • Use a few deliberate surface steps to communicate elevation.
  • Tune links, filled actions and semantic colours for their specific jobs.
  • Encode roles once, then inspect real screens across multiple conditions.
  • Measure contrast again whenever a surface or foreground partner changes.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in Typography & Colour
Typography & Colour

10 Best Color Contrast Checkers for Accessibility

Find a contrast checker for colour choices in websites and apps, from quick foreground-background tests to browser and desktop audits, with practical advice for testing real interface states.

Includes: Contrast checkerNoor HaddadNoor Haddad
Typography & Colour

Font Weights for UI: Regular, Medium, Semibold and Bold

Assign regular, medium, semibold and bold to clear interface roles. Build a practical weight map, avoid synthetic surprises and test emphasis in real UI components.

Includes: Contrast checkerArjun RamanArjun Raman
Typography & Colour

Dark Mode Typography: Adjust Weight, Contrast and Size

Tune dark-mode typography without blindly thinning every font. Compare text contrast, stroke weight, size and spacing using realistic reading samples and device checks.

Includes: Contrast checkerNoor HaddadNoor Haddad
Typography & Colour

Status Colors in UI: Success, Warning, Error and Info

Create a distinct semantic status palette with useful foregrounds, backgrounds, and borders while keeping brand accents separate from functional meaning.

Includes: Contrast checkerJonah WeissJonah Weiss
Typography & Colour

Dark Mode Design: Color Choices and Contrast Ratios

Build a dark theme with clear surface hierarchy, measured text contrast, and preference-aware CSS that stays comfortable without sacrificing readability.

Includes: Contrast checkerJonah WeissJonah Weiss
Typography & Colour

Small Caps, All Caps and Eyebrow Labels in Web Design

Use uppercase labels without sacrificing readability. Learn how tracking, genuine small caps, language-aware casing, and clear hierarchy work together in web typography.

Includes: Contrast checkerMateo FernándezMateo Fernández