Colors

How to Build a Dark Mode Color Palette

Shaheer Malik13 min read
ZepixoCOLORS
How to Build a Dark Mode Color Palette
On this page

A good dark mode color palette is not your light theme with the colors flipped. It is a system designed on purpose, with its own surfaces, its own text shades, and its own contrast checks. Done well, dark mode is calm, easy on the eyes, and just as readable as the light version. Done badly, it glares, muddies, and hides important UI.

This guide is for designers and developers who want a dark theme that looks premium and passes real contrast. I will cover how to build a ladder of surfaces, how elevation works without shadows, why you desaturate brand colors, how contrast changes in the dark, a full swatch table you can copy, and the pitfalls that trip up most first attempts. Let us build one properly.

What you'll learn

  • How to build a surface ladder instead of one flat background
  • How elevation reads through lightness, not just shadow
  • Why brand and accent colors need desaturating for dark mode
  • How contrast in dark mode differs from light mode
  • A copy-ready swatch table for a full dark palette
  • The common pitfalls and how to avoid each one

Start with surfaces, not a single background

The first mistake people make is using one dark color for everything. A real interface has layers. There is the page behind, the card on top, the menu above that, and a dialog above all. Each layer needs to feel distinct without a hard border.

So you build a surface ladder. This is a small set of dark neutrals that step gently lighter as elements rise toward the user. The base is the darkest, and each layer above it lifts a little. The eye reads the lighter surface as closer.

Base page#0f172a
Card#1e293b
Menu#334155
Dialog#475569
A surface ladder. Each layer lifts a little lighter as it rises toward the user.

Notice these are not pure black. Pure black surfaces can feel harsh and make shadows impossible to see. A very dark slate like #0f172a gives you room to layer and feels softer. The Zepixo Colors workspace builds these neutrals as a scale, so the steps stay even.

How elevation works in dark mode

In a light theme, you show elevation with a shadow. A card casts a soft gray shadow on a white page and reads as raised. In dark mode that trick weakens, because a dark shadow on a dark page is almost invisible.

So dark mode leans on lightness instead. The higher an element sits, the lighter its surface. This is why the surface ladder matters so much. The lift in lightness does the job the shadow used to do.

Combine subtle shadow with lighter surface

You can still use shadow, but as a quiet helper, not the main signal. A faint border or a soft glow plus a lighter surface reads cleanly. The lightness carries the depth, and the shadow adds a finishing edge.

Keep the steps small

Big jumps between layers look stripey and cheap. Small, even steps feel premium. Aim for a gentle climb, like 8 to 12 points of lightness between each layer, so the depth is felt more than seen.

Desaturate brand and accent colors

Here is the part most people miss. A vivid brand color that sings on white often screams on black. Saturated colors look more intense against dark backgrounds, and they can vibrate or strain the eye.

The fix is to desaturate and lighten your brand color for dark mode. You pull some chroma out and raise the lightness so the color sits calmly on a dark surface. It still reads as your brand, just dialed back for the new background.

Light theme
Brand 500 #5b5bd6
Dark theme
Brand 300 #a5b4fc
Use a lighter, softer shade of the brand on dark surfaces so it stays calm and readable.

This is where a perceptual model helps. In OKLCH you can lower chroma and raise lightness in a controlled way, keeping the hue steady. Our what is OKLCH guide explains why the model makes these shifts predictable.

Contrast in dark mode is different

Contrast does not behave the same way in the dark. The big rule is to avoid pure white text on a pure black background. That maximum contrast can cause a halo effect, where letters seem to glow and blur. It tires the eyes fast.

Instead, use a soft off-white for body text on dark surfaces. Something like #e2e8f0 reads clearly without the glare. Reserve near-white only for the most important headings, and even then keep it short of pure #ffffff.

Re-check every pairing

A pairing that passes in light mode can fail in dark mode, and the reverse is also true. You cannot assume the dark theme is safe just because the light one was. Run the whole dark palette through a contrast check.

The Zepixo contrast grid tests every shade against every other shade and toggles between the WCAG ratio and the APCA Lc value. Body text still wants 4.5 to 1 under WCAG, or an absolute APCA Lc near 75. See our WCAG color contrast explained and APCA contrast explained guides, and the official WCAG contrast minimum.

RoleLight valueDark valueWhy it changes
Body text#1e293b#e2e8f0Off-white avoids glare and halo
Muted text#64748b#94a3b8Lifts to stay readable on dark
Brand#5b5bd6#a5b4fcDesaturated so it does not vibrate

A full dark mode color palette swatch table

Here is a complete dark palette you can copy and adapt. It pairs a slate surface ladder with softened text and status colors. Every text pairing below clears the body-text contrast threshold against its surface.

TokenHexSwatchUse
surface-base#0f172aPage background
surface-1#1e293bCards, panels
surface-2#334155Menus, popovers
border#475569Dividers, outlines
text-primary#e2e8f0Body text
text-muted#94a3b8Secondary text
brand#a5b4fcLinks, primary accent
success#4ade80Positive status
warning#fbbf24Caution status
error#f87171Error status

Notice the status colors are also lighter than their light-mode versions. A deep red that works as error text on white would be too dark to read on a slate surface. Lifting it keeps the meaning and the contrast.

A step-by-step build

Let us put it together as a short recipe. Follow this order and the theme stays coherent.

  1. Pick a base surface that is dark but not pure black, like #0f172a.
  2. Build a surface ladder of three or four steps lifting gently lighter.
  3. Set body text to a soft off-white like #e2e8f0, not pure white.
  4. Take your brand color and lighten and desaturate it for dark surfaces.
  5. Re-derive each status color lighter so it reads on slate.
  6. Run the whole set through the contrast grid and fix any red cells.
  7. Preview on real buttons, cards, and inputs before you lock it.

Want to skip the math? Open the Zepixo Colors workspace to generate OKLCH scales, build a dark surface ladder, and check every pairing in the 11 by 11 contrast grid.

Common dark mode pitfalls

A few mistakes show up again and again. Knowing them in advance saves a lot of rework.

PitfallWhy it hurtsFix
Pure black backgroundHarsh, shadows vanish, halos appearUse a dark slate like #0f172a
Pure white body textGlare and letter halo, tiringUse off-white #e2e8f0
One flat surfaceLayers blur together, no depthBuild a surface ladder
Same vivid brand colorVibrates and strains on darkLighten and desaturate it
Inverting the light themeBroken contrast and odd huesDesign dark mode on purpose
Skipping the contrast checkFailing pairings ship to usersRun the grid on the dark set

The thread through all of these is the same. Dark mode is its own design, not a reflection of the light one. Treat it that way and most problems never appear.

Watch out for elevation overlays

Some systems tint higher surfaces with a faint brand color overlay. Used lightly this adds warmth, but heavy overlays shift your neutrals off-hue and clash with content. Keep any overlay very subtle, or skip it and let lightness do the work.

Mind images and screenshots

Photos and product screenshots designed for light backgrounds can look like glowing rectangles in dark mode. Add a subtle border or a small inset so they sit in the layout instead of floating. This small touch makes a dark interface feel finished.

Pairing dark mode with your light theme

Dark mode is most maintainable when it shares semantic tokens with light mode. A token like color-surface points to a light value in one theme and a dark value in the other. Then switching themes is a value swap, not a rewrite.

This is exactly how a token-based system pays off. You design both palettes once, map them to the same names, and the app flips between them cleanly. Our color design tokens guide covers the naming, and our accessible color system guide covers the contrast side.

Build the light and dark palettes side by side so they stay in sync. When you change a brand shade, you adjust both at once. The result is two themes that feel like one product, which is the whole goal.

Frequently asked questions

Should a dark mode background be pure black?

Usually not. Pure black makes shadows vanish and can cause a halo around white text. A dark slate like #0f172a feels softer, lets you layer surfaces, and reads more comfortably for long sessions.

Why do brand colors look too bright in dark mode?

Saturated colors appear more intense against dark backgrounds and can vibrate. Lighten the color and pull some chroma out so it sits calmly. A perceptual model like OKLCH makes that shift easy to control while keeping the hue.

How do I show elevation without shadows in dark mode?

Lean on lightness. The higher an element sits, the lighter its surface should be. A surface ladder of three or four steps does the work a shadow does in light mode, with a faint border or glow as a finishing touch.

Can I just invert my light theme to get dark mode?

No. Pure inversion produces harsh colors, broken contrast, and odd hues. Design the dark palette as its own system with softened surfaces and text, then re-check every pairing in a contrast grid.

What contrast should dark mode text meet?

The same targets apply. Body text wants 4.5 to 1 under WCAG, or an absolute APCA Lc near 75. The values change because the colors change, so you must re-test the dark palette rather than trusting the light one.

How many dark surfaces do I need?

Most interfaces are happy with three or four. A base page, a card layer, a menu or popover layer, and sometimes a dialog layer. Keep the lightness steps small and even so the depth feels premium, not stripey.

Design dark mode on purpose, build a calm surface ladder, soften your colors, and check every pairing. Do that and your dark theme will feel as good as your light one. You have got this.

S

Shaheer Malik

Founder of Zepixo — building the whole brand studio in one tab. Try Zepixo →

Related posts