How to Fix Low Contrast Text: 5 Fixes With Real Numbers
Your audit flagged a pair at 2.5:1 and now you need a fix that does not wreck the design. Good news: most failures are fixed by moving one color a few steps, not by redesigning the page. Every number below is computed with the WCAG 2.1 formula, so you can copy the exact hex values with confidence.
Fix 1: Darken the text (the usual winner)
Light gray body text is the single most common failure. The fix is a darker gray — same look, passing ratio:
| Gray on white | Ratio | Verdict (normal text) |
|---|---|---|
| #9CA3AF | 2.54:1 | Fail |
| #6B7280 | 4.83:1 | AA pass |
| #4B5563 | 7.56:1 | AAA pass |
One step (#6B7280) already clears AA; two steps (#4B5563) clears AAA and buys margin against future tweaks. Do not ship a pair that passes by 0.04 — aim for 5:1 or better.
Fix 2: Darken the background (for white text on brand color)
Bright brand colors make cheerful buttons and unreadable labels. Keep the hue family, darken the fill used behind text:
| White on blue | Ratio | Verdict (normal text) |
|---|---|---|
| #60A5FA | 2.54:1 | Fail |
| #3B82F6 | 3.68:1 | Fail (large text only) |
| #2563EB | 5.17:1 | AA pass |
The same ladder works for amber: white on #F59E0B is 2.15:1, on #D97706 is 3.19:1 (large text only), and on #B45309 is 5.02:1 (AA). The bright version can stay for large fills and icons — reserve the dark version for text.
Fix 3: Flip it — dark text on a light tint
Sometimes the brand color simply cannot go dark enough without looking wrong. Flip the pair instead: use the brand color as text on its own pale tint.
Dark blue #1E40AF on pale blue #DBEAFE scores 7.15:1 (AAA) while staying unmistakably blue. This flip is the standard fix for badges, tags, and alert banners.
Fix 4: Add a scrim over photos and gradients
White text directly on a photo fails wherever the photo is light. A translucent black overlay (scrim) darkens everything behind the text evenly:
| White over photo color #7A9CC6 | Resulting bg | Ratio | Verdict |
|---|---|---|---|
| No scrim | #7A9CC6 | 2.84:1 | Fail |
| 30% black scrim | #556D8B | 5.32:1 | AA pass |
| 50% black scrim | #3D4E63 | 8.51:1 | AAA pass |
In CSS: background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url(photo.jpg). If a scrim would ruin the photo, put the text on a solid chip instead — a dark rounded rectangle behind the text always scores exactly what the checker says it does. For gradients specifically, see the text-over-gradient guide and check the weakest point with the gradient checker.
Fix 5: Enlarge to large text — only when it truly is large
Large text (at least 18pt / about 24px, or 14pt / about 18.66px bold) only needs 3:1 at AA. That rescues some pairs legitimately:
But this is the most abused fix in accessibility. Bold body copy at normal size is not large text, and bumping a failing paragraph to 24px just to pass is a design change, not a fix. Use this only for text that was already meant to be a headline.
What not to do
- Do not judge by eye — hue difference deceives (red on yellow looks loud, scores 3.72:1).
- Do not rely on the "disabled" excuse for text users still need to read.
- Do not ship a 4.54:1 pair and hope nobody re-measures it — one hex digit of drift breaks it.
- Do not fix only the flagged pair — re-check placeholders, captions, error text, and hover states, which usually share the same failing gray.
- Do not stop at the ratio — run the fixed pair through the color blindness simulator, since a passing pair can still rely on hue alone.
Verify your fix in 10 seconds
Enter the before and after colors — the free checker computes the exact WCAG ratio and grades it against AA and AAA.
Open the Contrast Checker