Website design

Light and Dark Website Color Palettes: A Practical Guide

Published September 16, 2026

A useful dark theme keeps the same jobs for its colors while changing their brightness. Start with a background, readable text, a primary action, a supporting surface, and an accent.

1. Keep the roles consistent

Use surface for the page, ink for text, primary for links and buttons, secondary for cards, and accent for a small highlight. These names let components follow either theme without rewriting every style.

2. Try these two matching palettes

Light theme

Clear text, a calm surface, and one obvious next step.

Open this palette

Dark theme

Clear text, a calm surface, and one obvious next step.

Open this palette
Five semantic colors for each theme
RoleLightDark
surface#F8FAFC#101827
ink#172033#E2E8F0
primary#1D4ED8#93C5FD
secondary#E2E8F0#1E293B
accent#9A3412#FDBA74

The dark theme uses a brighter blue and orange so they remain readable against dark surfaces. It also uses a slightly lighter card background to show hierarchy. Avoid simply inverting every hex value.

3. Test the actual foreground and background

For normal text, WCAG AA requires at least 4.5:1; large text needs 3:1. Large means at least 24 CSS pixels, or about 18.7 pixels when bold. Compare the unrounded result. See W3C’s contrast explanation.

These examples use white button text in light mode and dark button text in dark mode. Recheck text on cards, links, hover states, focus indicators, and any new accent background in the contrast checker. A passing palette does not establish accessibility for the whole website.

4. Apply the roles with CSS

:root {
  --surface: #F8FAFC;
  --ink: #172033;
  --primary: #1D4ED8;
  --secondary: #E2E8F0;
  --accent: #9A3412;
  --on-primary: #FFFFFF;
}
@media (prefers-color-scheme: dark) {
  :root {
    --surface: #101827;
    --ink: #E2E8F0;
    --primary: #93C5FD;
    --secondary: #1E293B;
    --accent: #FDBA74;
    --on-primary: #101827;
  }
}
body { background: var(--surface); color: var(--ink); }
.card { background: var(--secondary); }
.button { background: var(--primary); color: var(--on-primary); }
a { color: var(--primary); text-decoration: underline; }

This follows the visitor’s system preference. If you add a manual theme switch, let its explicit choice override the media query and remember it locally. Check form controls, disabled states, and images in both modes; the color variables alone do not restyle them.

5. Adjust, check, and export

  1. Open one of the example palettes above in HueWiz.
  2. Edit a role and inspect the preview and contrast checks.
  3. Use Copy code or Download to export the palette. Each export represents the current theme; keep both sets in your theme stylesheet.
  4. Copy a share link to preserve all five roles for review.