How to build an accessible color palette: design tokens that pass WCAG AA from the start

Building an accessible color palette means defining text and background color pairs that pass WCAG AA from the start, rather than retrofitting contrast after design. A systematic approach uses a limited set of foreground colors (typically 2-3 text shades and 1-2 accent colors) paired with carefully chosen background tints.

WCAG level
WCAG AA
Minimum contrast (4.5:1+)
Example ratio
17.1:1
#1A1A1A on #FFFFFF
Category
Practical Tips
Accessibility knowledge base

Calculator

Back to Home

Contrast Checker

Check color contrast for accessibility.

0%
100%
Contrast Ratio
21.00:1

Large Text

Normal text sample.

AA Normal
Normal text (< 18pt)
AA Large
Large text (≥ 18pt)
AAA Normal
Normal text (< 18pt)
AAA Large
Large text (≥ 18pt)
UI Components
Graphical objects

How this is calculated

The practical approach is to define your accessible pairs as design tokens. For light mode: dark text (#1a1a1a to #333333) on light backgrounds (#ffffff to #f5f5f5). For dark mode: light text (#e5e5e5 to #ffffff) on dark backgrounds (#1a1a1a to #2d2d2d). Accent colors (brand blues, greens, reds) are the hardest to make accessible and should only be used on known-safe backgrounds, typically white or very light gray. Use a contrast checker to validate every pair in your token set before implementation.

Verdict

Define your accessible color pairs as design tokens and enforce them in code. A palette with 3 text colors × 3 background colors = 9 validated combinations is more maintainable than ad-hoc color picking. Use CSS custom properties to create semantic color tokens (--color-text-primary, --color-bg-surface) that map to accessible values.

More Practical Tips scenarios

Frequently asked questions

How many colors do I need in an accessible palette?
Start with 2-3 text colors, 2-3 background colors, and 1-2 accent colors. That gives you 6-9 validated text-background combinations, which covers most UI patterns. Add more only when a specific component requires it.