Accessibility-First Color Palettes: Designing for WCAG Compliance

May 28, 20267 min read

Why Start with Accessibility

Many teams pick colors for aesthetics first, then discover during QA that text contrast fails WCAG requirements. Fixing contrast after the fact means either darkening text (which changes the design intent) or reworking the entire palette.

An accessibility-first approach reverses this: start with colors that pass contrast checks, then refine aesthetically within those constraints. The result is a palette that looks good and works for everyone — including the estimated 300 million people worldwide with color vision deficiencies.

WCAG Contrast Requirements

WCAG 2.1 defines two conformance levels:

LevelNormal Text (< 18pt)Large Text (≥ 18pt bold or ≥ 24pt)UI Components
AA4.5:13:13:1
AAA7:14.5:1Not specified

Normal text includes body copy, labels, and navigation links. Large text includes headings and prominent labels. UI components covers icons, form borders, and focus indicators.

Contrast Ratio Explained

The contrast ratio compares the relative luminance of two colors:

Ratio = (L1 + 0.05) / (L2 + 0.05)

Where L1 is the lighter color and L2 is the darker color. Pure white (#FFFFFF) against pure black (#000000) gives a ratio of 21:1. Two similar grays might give 1.5:1.

Building an Accessible Palette Step by Step

Step 1: Define Your Backgrounds

Start with your surface colors — these are fixed because layouts depend on them.

:root {
  --bg-primary: #FFFFFF;    /* Light mode main background */
  --bg-secondary: #F1F5F9;  /* Light mode card background */
}

Step 2: Choose Text Colors That Pass

For each background, calculate the darkest shade needed to reach 4.5:1:

BackgroundMin AA TextExample Passing Color
#FFFFFF4.5:1#57534A (ratio: 7.1:1)
#F1F5F94.5:1#475569 (ratio: 6.8:1)

Never rely on the minimum. Choose a text color that exceeds 4.5:1 to provide comfortable reading, not just barely passing.

Step 3: Add Accent Colors with Contrast Verification

Accent colors (for links, buttons, badges) must contrast against their specific background:

:root {
  --color-accent: #2563EB;   /* Blue for links on white — ratio 4.6:1 ✓ */
  --color-success: #16A34A;  /* Green for badges — test against background */
  --color-warning: #CA8A04;  /* Yellow — often fails on white, needs dark text */
}

Yellow warnings are a notorious contrast trap. #CA8A04 on white gives only 2.8:1 — failing AA for normal text. Use a dark text on the yellow background instead:

.badge-warning {
  background-color: #FEF3C7;  /* Light yellow */
  color: #92400E;             /* Dark amber text — ratio 7.5:1 ✓ */
  border: 1px solid #F59E0B;
}

Dark Mode Accessibility

Dark mode is not simply inverting light mode colors. Contrast requirements still apply:

:root.dark {
  --bg-primary: #0F172A;
  --bg-secondary: #1E293B;
  --text-primary: #F1F5F9;   /* Ratio: 15.4:1 ✓ */
  --text-secondary: #94A3B8; /* Ratio: 5.6:1 ✓ */
}

Common Dark Mode Mistakes

MistakeWhy It FailsFix
Pure white (#FFF) text on dark bg21:1 ratio creates glare, causes eye strainUse off-white (#F1F5F9)
Low-opacity text (rgba(255,255,255,0.5))Calculated ratio may fall below 4.5:1Test actual rendered color
Saturated accent on dark bgSaturated colors vibrate against dark backgroundsDesaturate slightly or lighten
Same accent as light modeBlue #2563EB on #0F172A = 2.3:1 ✗Use #60A5FA — ratio 5.6:1 ✓

Color Blindness Considerations

Approximately 8% of men and 0.5% of women have some form of color vision deficiency. The most common types:

  • Deuteranopia (red-green): Cannot distinguish red from green
  • Protanopia (red-green): Reduced sensitivity to red light
  • Tritanopia (blue-yellow): Cannot distinguish blue from yellow (rare)

Design Rules

  1. Never use color alone to convey information. Always pair with text, icons, or patterns.
  2. Avoid red/green for success/error if they share similar luminance. Use shapes or labels as secondary indicators.
  3. Test your palette with a color blindness simulator. Free tools include Coblis and the built-in Chrome DevTools vision simulation.

Testing Workflow

  1. During design: Use the Stark plugin (Figma/Sketch) to check contrast in real time
  2. During development: Run axe-core or Lighthouse accessibility audits
  3. In CI: Add pa11y or accessibility-checker to your pipeline
  4. Manual spot-check: Use WebAIM Contrast Checker for borderline cases

Key Takeaways

  • Start with accessible contrast ratios rather than fixing them later
  • AA requires 4.5:1 for normal text, 3:1 for large text and UI components
  • Yellow and orange accents frequently fail on light backgrounds — use dark text on light fill instead
  • Dark mode needs its own contrast calculations — do not reuse light mode accent colors
  • Color should never be the only indicator of meaning — add icons, text, or patterns
  • Test with both automated tools and color blindness simulators

Try It Yourself

Build accessible palettes with built-in contrast checking using our Color Palette Generator. It flags WCAG failures in real time as you adjust colors.