Color Contrast Checker

If a ratio comes back at 4.49:1 you have failed AA on a rounding error, which tells you how blunt this measurement is. It compares relative luminance and nothing else — not hue, not saturation, not the font you set the text in.

Optional. Overrides the picker above when filled in.
Optional. Overrides the picker above.
Color Contrast Checker — WCAG AA and AAA Ratio for Text and UIBuildFigure

How the ratio is computed

WCAG defines contrast as (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter of the two relative luminances. Relative luminance is not the average of the RGB channels. Each channel is first divided by 255, then linearised — c / 12.92 when c is at or below 0.03928, and ((c + 0.055) / 1.055) ^ 2.4 above that — which undoes the sRGB transfer curve. The three linear values are then weighted 0.2126 red, 0.7152 green, 0.0722 blue, reflecting how much each contributes to perceived brightness.

Two consequences fall out of the weighting. Green carries roughly seven times the luminance weight of blue, so pure blue text on black scores far better than pure green text on black even though the blue is much harder to read. And the 0.05 term in the numerator and denominator is what bounds the scale: black on white gives (1 + 0.05) / (0 + 0.05) = 21 exactly, and any color against itself gives 1. Those two reference points are worth checking in any contrast tool you use, this one included.

What AA and AAA actually require

Success criterion 1.4.3 (AA) asks for 4.5:1 for normal text and 3:1 for large text. Criterion 1.4.6 (AAA) raises those to 7:1 and 4.5:1. Large text means 18pt, which is 24px, or 14pt bold, which is 18.66px. Criterion 1.4.11 (AA) extends the 3:1 requirement to user interface components and meaningful graphics — the border of an input, a focus indicator, the bars of a chart, an icon that carries information on its own.

The exclusions matter as much as the thresholds. Disabled controls are exempt. Pure decoration is exempt. Logotypes are exempt. Text that is part of a photograph is exempt. None of that means those things are readable; it means the criterion does not apply, which is a different statement and one that is regularly used to close a ticket that should have stayed open.

How the suggested colors are chosen

The text color is converted to HSL, hue and saturation are pinned, and lightness is walked from 0 to 100 in whole steps. Every lightness that clears the target ratio is a candidate, and the one nearest the original lightness wins. That keeps the suggestion recognisably the same color rather than handing you an unrelated one.

Against a mid-tone background — grey around 50% lightness — there may be no answer at all, because both darkening and lightening the text run out of ratio before reaching 4.5:1. That is when the tool also offers a background adjustment. Treat either suggestion as a starting point: in practice you will snap to the nearest token in your palette and re-check, not ship a value a converter produced.

Where this measurement stops being useful

The calculation assumes two flat, fully opaque colors. Semi-transparent text, text over a gradient, and text over a photograph all have a different effective contrast at every pixel, so the honest approach is to sample the worst point with an eyedropper and test that. Text shadows, outlines and scrims do not enter the formula either, even though they can make text substantially more legible in practice.

The formula also predates most of what is known about how thin type and large color areas behave. Light text on a dark background at the same measured ratio often reads as heavier than the reverse, because of how the eye handles glare. A hairline weight at 4.5:1 can be worse than a medium weight at 4.0:1. APCA, drafted for WCAG 3, models some of this by accounting for text weight and polarity, but it is not a normative requirement anywhere yet, so 2.x ratios remain what conformance is measured against. Meet the number, then look at the result.

Questions people ask

What is the contrast ratio of black on white?

Exactly 21:1, and that is the maximum the WCAG formula can produce. White has a relative luminance of 1 and black has 0, so the ratio is (1 + 0.05) / (0 + 0.05) = 21. Every other pair falls somewhere between 21:1 and 1:1. It is a useful sanity check on any contrast tool: if black on white does not come back as exactly 21, the tool is not implementing the specified formula.

Why does #777777 on white fail AA when it looks fine to me?

It comes to 4.48:1, just under the 4.5:1 needed for normal text. It looks fine on a calibrated laptop screen in a lit room to someone with unimpaired vision, which is the exact set of conditions the threshold exists to look past — a phone in sunlight, an old panel with a shifted gamma, or a reader with moderately reduced contrast sensitivity. #767676 is the well-known grey that clears the bar at 4.54:1, and one hex step is the entire difference.

My text passes 4.5:1 but is still hard to read.

The ratio only measures luminance difference. A saturated red on a saturated blue can pass while producing chromatic aberration that makes the edges swim. Very thin weights, tight letter spacing, long line lengths and low ambient light all degrade legibility without changing the number at all. Contrast is one input among several, and the check that catches the rest is putting the real text at the real size in front of someone.

Do I need to check contrast for disabled buttons and placeholder text?

Disabled controls are explicitly exempt from 1.4.3 and 1.4.11. Placeholder text is not exempt — it is text, so the 4.5:1 rule applies, and the common pale-grey placeholder usually fails it. The deeper problem with placeholders is that they vanish on focus and are frequently used in place of a label, so the accessible fix is normally a visible label rather than a darker grey.

Does this tool handle alpha or opacity?

No. It compares two opaque colors. If your text is rgba with an alpha below 1, or sits on a translucent panel, composite the color first — blend it against whatever is behind it — and enter the resulting flat value. Entering the unblended color will report a contrast you do not actually have.

Related