In short
WCAG AA requires a 4.5:1 contrast ratio for normal text and 3:1 for large text and UI components — the reliable way to meet this consistently is building the ratio requirement into your color scale itself, so every semantic text/background pairing passes by construction rather than by late-stage checking.
What the standard actually requires
WCAG 2.1 AA requires a contrast ratio of at least 4.5:1 between normal text and its background, and 3:1 for large text (roughly 18px+ regular or 14px+ bold) and for meaningful UI components like input borders and icons. AAA, a stricter level, raises normal text to 7:1. Most products should target AA as the baseline, treating AAA as a bonus where achievable.
Where contrast actually fails in practice
- Placeholder text in form fields, often set to a light gray that fails contrast against a white background.
- Disabled state text, sometimes so faint it fails contrast for anyone still expected to read it (disabled doesn't mean invisible).
- Text over images, where a gradient or scrim isn't strong enough for the underlying image's variability.
- Brand colors used directly as text color — a vibrant brand blue that looks great as an accent often fails 4.5:1 against white when used for body text.
- Dark mode, where a color system designed and checked only in light mode is assumed (often wrongly) to also pass in its dark-mode mapping.
The reliable fix: build it into the scale, not the component
Checking contrast per-component, after the fact, doesn't scale — someone will eventually reach for a token that fails, in a context nobody tested. The durable fix is designing your color scale so that specific semantic pairings (say, color-text-primary on color-surface-primary) are guaranteed to clear the ratio by construction, because you chose the scale steps with that constraint in mind from the start.
Testing tools worth using
Browser dev tools (Chrome and Firefox both have a contrast checker built into the color picker in the inspector) and dedicated tools like the WebAIM Contrast Checker let you verify a specific pairing quickly. For a whole product, an automated accessibility audit tool run against real rendered pages catches contrast failures at scale far faster than manual spot-checking.
Contrast isn't just text
UI components — button borders, form field outlines, icons that convey meaning, focus indicators — also need to meet the 3:1 threshold against their background. A form field with a border so light it's nearly invisible fails accessibility even if the label text inside it passes.
Don't rely on color alone
Contrast ratio is necessary but not sufficient — information conveyed only through color (a red border meaning "error," with no icon or text label) fails a different but related accessibility principle. Pair color-coded meaning with a redundant signal: an icon, a text label, an underline — so the information survives for users who can't distinguish the colors at all.
A practical rollout
Audit your existing color scale's semantic pairings against the ratio requirements first — this usually surfaces a small number of specific token combinations that need adjusting. Fix those at the token level once, rather than patching individual components as failures get reported.
Common questions
What's the minimum contrast ratio I need?
4.5:1 for normal text and 3:1 for large text and meaningful UI components meets WCAG 2.1 AA, the standard most products should target as a baseline.
Does dark mode need separate contrast checking?
Yes — a color system that passes contrast checks in light mode isn't automatically compliant in dark mode; each semantic pairing needs to be verified in both mappings.
Is passing contrast ratio enough for accessible color use?
No — information conveyed only through color still needs a redundant signal (icon, label, pattern) for users who can't distinguish the colors, even if the ratio itself passes.