Color contrast: your colors pass the check and still fail
Lighthouse scored our test page 95 while its text failed contrast. Learn which color pairs teams forget, what the tools miss, and how to check them.
By Frontsiter · Published · 3 min read
The problem
A contrast checker said your brand color passes, but labels inside cards and tinted panels are hard to read. A color has no single contrast: every pair of text color and background has its own ratio. The check measured the color on the page background, and the labels sit on other backgrounds.
This is not a beginner's mistake. In 2026, WebAIM found low-contrast text on 83.9% of the top one million home pages, the sites of the biggest companies on the web. The usual cause is a single check: the colors are tested once against the page background, and the other backgrounds and states are never tested. We nearly made the same mistake on Frontsiter.
Low contrast makes text hard to read for people with low vision and for people whose contrast vision has weakened with age.
In three minutes, this guide shows the color pairs that teams forget to check, what the tools missed in our tests, and three steps to catch them before release.
On white
5.4:1 · passes
On a light tint
4.7:1 · passes
On a stronger tint
3.9:1 · fails
What the tools missed in our test
A contrast checker tests only the pair you give it. On our test page, axe and Lighthouse caught low-contrast text on plain backgrounds but missed hover states, input borders, focus outlines, icons, and placeholder text. Lighthouse also ignored text over gradients, background images, and ::before backgrounds, and still scored the page 95 for accessibility.
The fix
1. Plan it with the palette. When you choose the colors, write down every background each text color will sit on: the page, cards, tinted panels, the footer, and hover and selected states. Check those pairs before you build components, and again whenever a component gets a new background or state.
2. Use the right rule for each pair.
- Normal text: at least 4.5:1.
- Large text (24px, or 18.67px bold, which WCAG gives as 18pt and 14pt bold): at least 3:1.
- Input borders, custom focus outlines, and icons: at least 3:1 against the colors next to them.
Do not round up: 4.49:1 fails. Disabled controls and logos are exempt. The full rules are in WCAG: Contrast (Minimum) for text and Non-text Contrast for the rest.
3. Fix a failing color and keep the brand. Darken it a little in the same hue until it passes, or write down the backgrounds where it is not allowed. Write that rule next to the color, in the file that defines your palette (here globals.css):
:root {
/* Accents only: 5.4:1 on white, 4.7:1 on tint. */
/* Never on tint-strong (3.9:1). */
--color-orchid: #a04d83;
}Check that it works
- Every page: run axe DevTools or Lighthouse. Both catch low-contrast text on plain backgrounds. The axe extension also lists what it could not check as "needs review"; Lighthouse leaves those out.
- One pair: in the browser's developer tools, open the color picker for the text color. It shows the ratio and whether it passes. Use the
:hovbutton in the Styles panel to check hover and focus states. For two colors from a design file, use the WebAIM Contrast Checker. - By hand: check what the tools skip: borders, focus outlines, icons, placeholder text, and text over gradients, images, or
::beforebackgrounds. In our test, the developer tools read a::beforebackground as white and showed a pass for text that failed.
Frontsiter's logo orchid, #a8518a, passed on white but failed on the site's tinted panels (4.35:1), so the site uses an orchid about 5% darker, #a04d83, and never puts it on the strongest tint.
