Accessible Palettes
Curated color sets that pass WCAG AA at every step — plus the principles for building your own accessible palette from scratch.
Ready-made accessible palettes
Each palette below is designed so that all foreground/background pairs meet WCAG AA or AAA, and all steps remain distinguishable under common CVD types.
1. Neutral Pro — 8 colors
A balanced palette for professional interfaces. Cool grays with a confident blue primary. All text pairings pass AAA.
2. Editorial Warm — 8 colors
Warm neutrals with a burgundy accent. Designed for editorial and lifestyle products. All text pairings pass AA or AAA.
3. Slate Tech — 8 colors
A cool, high-contrast palette for developer tools and dashboards. Neutral slate with an indigo primary and a bright cyan accent.
4. Nature Calm — 8 colors
Earth tones with a forest green primary. Perfect for wellness, sustainability, and nature-adjacent products.
5. High Contrast — 8 colors
Maximum readability palette. Ideal for accessibility-first products, kiosks, and long-form reading.
6. Muted Modern — 8 colors
Desaturated palette for minimal design. Low saturation but sufficient contrast for all text pairings to pass AA.
Universal semantic tokens
Regardless of which palette you use, these are the roles a complete accessible system needs. Each role has a recommended contrast target:
| Token | Role | Contrast on surface |
|---|---|---|
--color-text | Primary body text | ≥ 4.5:1 (AA), aim for ≥ 7:1 (AAA) |
--color-text-secondary | Secondary / muted text | ≥ 4.5:1 (AA) |
--color-text-tertiary | Hints, captions | ≥ 4.5:1 (AA) if informational |
--color-border | Borders, dividers | ≥ 3:1 (AA UI) where required for interaction |
--color-surface | Base surface | — |
--color-surface-raised | Cards, modals | — |
--color-primary | Brand actions | ≥ 4.5:1 text on white/black |
--color-primary-text | Text on primary | ≥ 4.5:1 (AA) against primary |
--color-success | Success states | ≥ 4.5:1 text on white/black |
--color-warning | Warning states | ≥ 4.5:1 text on white/black |
--color-danger | Error states | ≥ 4.5:1 text on white/black |
--color-info | Informational | ≥ 4.5:1 text on white/black |
Note that the semantic foreground tokens (like --color-success) often need two variants: one dark enough to sit on light surfaces, and one light enough to sit on dark surfaces. This is why every token has a paired dark-mode override.
Copy a palette as CSS
Every palette on this page can be copied as CSS custom properties. Here's the Neutral Pro palette as a ready-to-paste block:
:root {
/* Neutral Pro — accessible palette */
--color-text: #111827;
--color-text-body: #374151;
--color-text-secondary: #6b7280;
--color-border: #e5e7eb;
--color-surface: #f9fafb;
--color-primary: #4f46e5;
--color-accent: #0ea5e9;
--color-success: #10b981;
--color-warning: #d97706;
--color-danger: #dc2626;
--color-info: #2563eb;
}
[data-theme='dark'] {
--color-text: #f9fafb;
--color-text-body: #d1d5db;
--color-text-secondary: #9ca3af;
--color-border: #374151;
--color-surface: #111827;
}
Building your own accessible palette
-
Choose a primary huePick a brand color that will anchor the system. Then generate a 50–950 scale from it (see the shades generator).
-
Build a neutral scaleUse a warm, cool or neutral gray scale with 9–12 steps. Neutrals carry more of the interface than the primary color.
-
Assign semantic rolesMap specific scale values to semantic tokens: text, body, secondary, border, surface, success, warning, danger, info.
-
Test every pairCheck every foreground/background combination you use against WCAG AA. Fix failures by adjusting the darker or lighter end of the pair.
-
Simulate CVDRun the palette through the color blindness simulator. Ensure that status colors remain distinguishable and that meaning is never carried by hue alone.
-
Add dark modeDark mode does not simply invert light mode — colors need to be re-derived. Flip the neutral scale and adjust primary, success, warning and danger so they remain readable.
Quick-reference: contrast ratios
| Use | Target |
|---|---|
| Body text on surface | ≥ 4.5:1 (AA) |
| Secondary text | ≥ 4.5:1 (AA) |
| Large headings | ≥ 3:1 (AA large) |
| Icons / borders (interactive) | ≥ 3:1 |
| Focus rings | ≥ 3:1 |
| Reading-intensive text | ≥ 7:1 (AAA) |
| Disabled text | No requirement |
Related resources
Frequently asked questions
What makes a palette accessible?
A palette is accessible when every foreground/background pairing used in the interface meets the WCAG contrast requirements (4.5:1 for normal text, 3:1 for large text and UI), and when information is never conveyed by color alone. Distinguishable lightness values and support for dark mode are also important.
How many colors should an accessible palette have?
Most accessible systems use 5 to 8 core colors: a primary brand color, two neutrals (light and dark), a success, a warning, an error, and an informational color. Each color then expands into a scale of 5 to 11 shades for use across surfaces, text and interactive states.
Can a bright neon color be part of an accessible palette?
Yes, but not alone. Bright colors often fail contrast on both white and black backgrounds. They work best as fills, badges or accents with dark or light text on top — never as the direct foreground color for body text.
Are accessible palettes boring?
No. Accessible palettes are often more refined because they force deliberate choices about hierarchy and contrast. Many of the most distinctive brands in design — Stripe, Linear, Vercel, Apple — use palettes that pass WCAG AA comfortably.
Do I need a separate dark mode palette?
Yes. Dark mode is not a simple inversion. Colors must be re-derived: neutrals flip, but primary, success, warning and danger all need to be adjusted so they remain readable on dark surfaces. Typically this means using lighter variants of each color in dark mode.