~/allthedamn.tools

Color Contrast Checker

Check text against WCAG AA and AAA, then fix a failing colour in one click.

runs entirely in your browser
4.54:1

Passes AA at every text size, and AAA for large text only.

  • AA · normal text · 4.5:1 pass
  • AA · large text · 3:1 pass
  • AAA · normal text · 7:1 fail
  • AAA · large text · 4.5:1 pass

Large text, 24px: passes at 3:1

Body text at 16px. This is the size most of a page is set in, and the size the 4.5:1 threshold exists for.

Small print at 14px: captions, footnotes, form hints, the legal line nobody budgets contrast for.

Checked on your device. Nothing you enter leaves this page. The share link carries the two colours and nothing else.

What the ratio means, and where the four numbers come from

Contrast ratio compares the relative luminance of two colours on a scale from 1:1 (the same colour twice, invisible) to 21:1, pure black on pure white. It is not a measure of how different two colours look; it is a measure of how different their brightness is. That is why two colours that are obviously distinct to you, a red and a green of similar lightness, can sit at 1.2:1 and be unreadable to a great many people.

WCAG 2.2 sets four thresholds and this page checks all of them at once. Level AA, the one referenced by most legislation and most procurement contracts, asks for 4.5:1 for normal text and 3:1 for large text. Level AAA asks for 7:1 and 4.5:1. Large text means 18pt (about 24px) or 14pt bold (about 18.66px); everything else is normal text, including the 14px small print where contrast is most often quietly dropped.

The thresholds are inclusive: a pair measured at exactly 4.5:1 conforms at AA. The ratio here is rounded DOWN to two decimals for that reason, so the number you read can never look like it clears a threshold the pair does not actually clear. A checker that displays 4.4996 as 4.50 next to a fail badge is arguing with itself. Worth knowing if you cross-check: most other checkers round to nearest instead, so a pair like #777777 on white reads 4.47 here and 4.48 elsewhere. Both are the same underlying 4.4781, and both fail AA.

The fix button, and when it honestly cannot help

Knowing a colour fails is the easy half. The useful question is what to use instead, and the answer almost nobody wants is 'black'. The fix buttons here walk your text colour's lightness (up or down, whichever is nearer) until it reaches the threshold, holding its hue and saturation. A terracotta that fails AA comes back as a darker terracotta, not as a neutral, so the result is still recognisably your colour.

The walk happens in OKLCH rather than HSL, which matters more than it sounds. HSL's lightness is perceptually dishonest: it claims a saturated yellow and a saturated blue at 50% lightness are equally light, and they are nowhere near it. Nudging lightness in HSL slides the colour through hues a designer would not accept as the same colour. OKLCH was fitted to how brightness is actually perceived, so the adjusted colour reads as the original, adjusted.

Sometimes there is no answer, and the tool says so rather than returning its best attempt. Against a mid-grey background, no lightness of any colour reaches 7:1. Going all the way to white gets to about 3.9:1, and all the way to black about 5.3:1. When no lightness can reach the target, the background has to move too, or the hue has to change. A tool that silently hands back the closest miss gives you a colour that still fails, and nothing on screen tells you.

Why there is a preview panel and not just a number

The panel below the grid renders real, selectable text in the two colours you picked, at 24px, 16px and 14px. That is deliberate: a pair of swatches side by side tells you almost nothing about whether body copy is comfortable, and the 4.5:1 threshold exists for body copy specifically. Text at 14px on a pairing that scrapes AA looks noticeably worse than the same pairing at 24px, and seeing that is the point.

It is also worth being clear about what a passing ratio does not promise. WCAG contrast is a floor, not a guarantee of readability: it says nothing about font weight, about thin display faces at small sizes, about how the page looks in sunlight, or about the several forms of colour vision deficiency that leave luminance intact while destroying hue separation. Two colours can pass AAA and still be a bad pairing for a red-green colour-blind reader if hue is doing work that brightness is not.

The colours also travel in the page address, so a checked pair is a link you can paste into a ticket or a design review rather than a screenshot somebody has to re-enter. Nothing is uploaded to do any of this: the arithmetic runs in your browser, which is why it keeps working with the network off.

fair questions

What contrast ratio does WCAG require?
Level AA requires 4.5:1 for normal text and 3:1 for large text. Level AAA requires 7:1 and 4.5:1. AA is the level most accessibility legislation and procurement rules reference, so it is the practical target for most work. The thresholds are inclusive: a pair measured at exactly 4.5:1 passes AA for normal text.
What counts as large text?
18pt or larger, which is about 24px, or 14pt bold, which is about 18.66px. Everything smaller is normal text and needs the higher 4.5:1 ratio at AA. The distinction exists because larger letterforms have thicker strokes and stay legible at lower contrast. It is about the rendered size on screen, not about the heading level in your markup.
What do I do if my brand colour fails AA?
Use the fix button. It finds the nearest lightness of that same colour which reaches the threshold, keeping the hue and saturation, so you get a darker or lighter version of your brand colour rather than a neutral. If no lightness can reach it (which happens against mid-tone backgrounds), the page says so instead of returning a near miss, and your options are to change the background too, or to reserve the brand colour for large text, headings and non-text elements where the 3:1 threshold applies.
Why does another checker show a slightly different number?
Almost always because of rounding, not because either is wrong. This page rounds down to two decimals so a displayed number can never look like it clears a threshold the colours do not actually clear; most other checkers round to nearest. #777777 on white is 4.4781, which reads as 4.47 here and 4.48 on WebAIM. Both are the same measurement, and a fail against AA either way. A genuine disagreement would be a much larger gap, and usually means one tool is sampling a colour after opacity or a background image has changed it.
Does a passing contrast ratio guarantee my page is accessible?
No. Contrast is a floor, not a finish line. The ratio is computed purely from luminance, so it says nothing about font weight, thin display typefaces at small sizes, glare, or colour vision deficiency. Two colours can pass AAA and still be a poor pairing for a red-green colour-blind reader if hue is carrying meaning that brightness is not. Never use colour alone to convey information, and test with real text at real sizes.
Why do you calculate the fix in OKLCH instead of HSL?
Because HSL's lightness is perceptually inaccurate: it treats a saturated yellow and a saturated blue at 50% lightness as equally light, and they are visibly nowhere near it. Adjusting lightness in HSL therefore drags a colour through shades that read as a different colour. OKLCH was fitted to human brightness perception, so moving along its lightness axis gives you the same colour, lighter or darker, which is what makes the suggestion usable rather than merely conformant.
Do my colours get uploaded anywhere?
No. The whole calculation is arithmetic on two colours and it runs in your browser, so nothing is sent to a server and the page keeps working offline once loaded. The colours do appear in the page address so that a result is shareable as a link, but that URL is only ever written locally in your address bar.