Color contrast
Light grey text on white looks refined in a mockup and disappears on a phone in the sun. Contrast is the most common accessibility failure on the web, and one of the cheapest to fix.
What fails
Contrast is the difference in brightness between text, or an important shape, and what is behind it. WCAG measures it as a ratio from 1:1 (white on white) to 21:1 (black on white). Below a certain ratio, people with low vision cannot read the text at all, and everyone else reads it more slowly.
These are the thresholds for level AA, the one laws and standards ask for:
| What | Minimum ratio |
|---|---|
| Normal text | 4.5:1 |
| Large text (24 px, or 18.66 px bold) | 3:1 |
| Icons, field borders, focus rings, chart lines | 3:1 |
It fails in the same few places on almost every site:
Grey body text. #999 on white is 2.8:1. It is the most common single finding on the web, and it usually comes from a design system that chose a “soft” grey once and used it everywhere.
Placeholders and helper text. The small grey text under a field, or inside it, is often the lightest text on the page and also the one that explains what to type.
Brand color buttons. White text on a mid-tone brand color (orange, light blue, green) regularly lands between 2.5:1 and 4:1.
Text over images. A headline on a hero photo can pass on one side and fail on the other.
Input borders. A field outlined in very light grey is hard to find at all, which is why non-text elements have their own 3:1 rule.
How to test it
One minute per page, no setup.
- Open the page in Chrome and right-click any text, then choose Inspect.
- In the Styles panel, click the small color square next to
color. The picker shows the contrast ratio and a tick or a cross for AA and AAA. - Check the lightest text you can find: placeholders, captions, footer links, prices, dates.
- Check one button of each color, with its text.
- Check the border of a form field and the focus ring when you Tab onto it.
To check a single pair, such as your brand color on white, use the color contrast checker: it gives the ratio and, if it fails, the nearest color that passes.
For a whole page at once, an automated analysis is the right tool here: contrast is a calculation, so the free website checker finds every failing pair reliably and tells you the exact ratio.
How to fix it
Darken, do not redesign. Most failures are fixed by moving a grey a few steps darker. #767676 is the lightest grey that passes 4.5:1 on white, and on screen it still reads as grey.
/* 2.8:1, fails */
.caption { color: #999999; }
/* 4.5:1, passes, still looks light */
.caption { color: #767676; }
Fix it in the tokens, not page by page. If your site uses variables or a design system, change the value once (--text-muted, --border, --placeholder) and every instance is fixed together.
For brand buttons, change the text or the shade. Dark text on a light brand color often passes where white text does not. If the brand color must stay with white text, use a darker shade of it for buttons only.
Put a layer behind text on images. A solid band or a semi-opaque overlay gives you a predictable background to measure against.
.hero-title {
background: rgb(0 0 0 / 0.6);
color: #fff;
}
Never rely on color alone. Errors get a message and an icon, links in body text get an underline, and charts get labels or patterns as well as colors.
Why it matters commercially
Low contrast does not stop a purchase the way a keyboard trap does. It slows everybody down a little and stops some people completely, and it is usually spread across every page. That is why it is worth fixing at the source: a handful of color values changed in one place removes dozens of findings from an audit, and the site is easier to read for every visitor.