Accessible Color Pair Suggester

Check a text and background pair against WCAG contrast and get the closest passing fix that keeps your hue instead of replacing the colour.

Contrast ratio
WCAG level
The quick brown fox jumps over the lazy dog
Small text at 14px — the hardest case for contrast.

Ratios follow the WCAG 2 formula. 4.5:1 is the legal-ish bar for normal text in most accessibility standards; large text (18pt / 24px, or 14pt bold) only needs 3:1.

At AAA there are backgrounds with no fix at all, and no tool can do better

The suggestion works by holding your hue and saturation and walking the lightness until one direction clears the target. If neither pure black nor pure white would clear it, there is nothing to return — and the shared contrast code used to describe that as impossible. It is not. Running every grey background from black to white at each of the three targets:

TargetBackgrounds with no fixShare
3:1 0 of 256 0.0%
4.5:1 0 of 256 0.0%
7:1 59 of 256 23.0%

Nearly a quarter of the greys, and the useful mid-tones rather than anything exotic. Against #5a5a5a, white reaches only 6.90 and black only 3.04, so at 7:1 no colour of any hue can sit on it. That is a prediction rather than a surprise: a colour passes against something lighter only if its luminance is at most 1.05/r − 0.05, and against something darker only if it is at least 0.05r − 0.05. At 3:1 and 4.5:1 those limits overlap; at 7:1 they cross and leave a 20%-wide band from 0.1 to 0.3 where neither works. The 59 failing greys are exactly that band, to the last one. The same background is comfortable at 3:1, which is why the lower bars never fail.

And one more used to fail that did not have to

It was 60 before this was written. The search steps a hundredth of a unit of lightness at a time from wherever your colour starts, and the guard keeping it inside the range stops it just short of the ends. #595959 sits a whisker below the band — pure white clears 7:1 against it at 7.005. But reaching pure white from the sample colour needs a step of 0.2333, and the loop tests 0.23 and then stops, landing one hundredth short at a ratio under 7. A fix existed, was a hundredth away, and was reported as impossible. It now checks the two endpoints before giving up, and #595959 returns pure white. One background in 256 is a small return — but “no colour works” and “no colour within a hundredth of the ones I tried works” are not the same claim, and the first is what the interface says.

What it does when it succeeds

Every colour it returns genuinely meets the target it was asked for — 709 suggestions checked against their own bar, none short. A colour that already passes comes back untouched rather than being nudged for no reason. Hue is kept, with a caveat worth stating plainly. Of 550 fixes, 539 still have a hue worth measuring and none drifts as much as 1.6 degrees — 0.39 among the mid-lightness ones, with a median across everything of 0.11. The other 11 land at one extreme of the range or the other, where the three channels have converged and pure white and pure black have no hue at all. Measuring drift there measures the colour space running out of room, not the search wandering.

It also has a preference. The loop tests a darker and a lighter candidate at each step and returns the darker when both arrive together, so ties go dark: 138 of 200 fixes at 4.5:1 darkened the text rather than lightening it. Nothing is wrong with that — it is a rule, not a judgement about your palette, and if you wanted the lighter one it is the same distance away in the other direction.

How to use

  1. Enter your text and background colours.
  2. Read the current contrast ratio.
  3. Accept the suggested adjustment or nudge it yourself.
  4. Verify the result at the size you will actually use.

Frequently asked questions

Why adjust lightness rather than pick a new colour?

Because contrast depends almost entirely on luminance, and hue barely affects it. Darkening or lightening a colour while holding its hue and saturation makes it pass while keeping it recognisably the brand colour, which is what makes the fix acceptable in practice.

What ratio do I need?

4.5 to 1 for normal body text at level AA, 3 to 1 for large text of 18 point or 14 point bold, and 3 to 1 for interface components and meaningful graphics. Level AAA raises the body text requirement to 7 to 1.

Why does my brand colour fail so often?

Because brand palettes are chosen for distinctiveness and mood, not luminance contrast, and mid-tone saturated colours are the worst offenders. A vivid mid blue or red simply is not far enough in luminance from white to carry body text, however striking it looks.

Can I use the failing colour anywhere?

Yes, in plenty of places. Large display type, decorative elements, backgrounds behind darker text, and non-informational graphics have lower requirements or none. The constraint applies to text and to elements that convey meaning, not to every use of the colour.

Is the contrast formula perfect?

No, and this is worth knowing. The current calculation is known to misjudge some pairings, particularly light text on dark backgrounds, and a replacement algorithm has been under development for years. Meeting the current standard is still the right target — it is what conformance is measured against.

Does dark mode need checking separately?

Absolutely. Contrast ratios do not carry over between themes, and a palette that passes on white frequently fails on a dark background. Pure white text on pure black is also worth avoiding, since the extreme contrast causes halation that makes text harder to read for some people.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.