Contrast Checker
WCAG AA and AAA verdicts for any foreground and background pair.
Preview
Both samples use the pair you are testingThe button is filled with your text colour and labelled in your background colour — the same pair the copy above it tests, read the other way round. A label set in the background colour on a background-coloured button is a different test, and not the one a user has to read.
Ratio
- Text luminance
- —
- Background luminance
- —
- Black on this background
- —
- White on this background
- —
Colours
X swaps themThe ratio is computed from the two opaque values and nothing else. If your text sits on a translucent panel, flatten it against whatever is behind that panel first, then test the flattened colour.
The ratio is half the story. It measures two colours, not the type set in them. A 300-weight grotesque at 16px needs considerably more than 4.5:1 to read as comfortably as a 600-weight at the same size, because thin stems antialias into the background and shed the contrast the arithmetic promised. If a face is light, or the text is small, treat 7:1 as the working target and 4.5:1 as the emergency exit.
The background sets a ceiling
The ratio depends on both colours, and the background is the half that decides how much room there is. For any background there are exactly two extreme foregrounds — black and white — and each has a fixed best case against it. If neither reaches the threshold you need, no third colour will either, because everything else sits between them.
best possible ratio against a background of luminance L:
against pure black (L + 0.05) / 0.05 = 20L + 1
against pure white 1.05 / (L + 0.05)
L = 0.18, a mid grey near #767676:
against black 4.6:1 just clears AA, with nothing to spare
against white 4.6:1 the same, by symmetry
L = 0.35, a light panel:
against black 8.0:1 comfortable
against white 2.6:1 fails for anything
That first row is the trap. There is a band of mid-tone backgrounds on which nothing reaches a comfortable ratio, because black and white are the best you can do and both land near the floor. A page built on a mid-grey panel can pass an audit with pure black text and still be tiring to read, and no amount of fiddling with the text colour will improve it — the panel is the thing that has to move.
Measure the worst pixel, not the average one. A pair of colours is easy to check; a page is not a pair. Text over a photograph, over a gradient, over a translucent panel or over a hover state that changes the background underneath it is a different measurement in every position, and the criterion applies to all of them. Sample the lightest and darkest points behind the text and check those — the middle of the image is the one place the number will always look fine.
Half the rule is about things that are not text
WCAG 1.4.11 applies the 3:1 threshold to the parts of an interface a person needs in order to operate it: the border of an input, the ring that appears when something is focused, the on and off states of a toggle, the outline of an icon button, the segments of a chart. It is a requirement rather than a polish item, and the failure mode is not aesthetic. An input whose border is invisible against the panel behind it is an input that some people cannot find. A focus ring that disappears on a dark background is a keyboard user who has lost their place on the page.
These are also the measurements most often skipped, because a designer checking a page will check the type. A form on a white card with a pale grey border at 1.4:1 looks tidy in a mockup and is unusable to anyone who does not already know where the fields are. The same applies to the checked and unchecked states of a control: a toggle that differs only in the position of a knob is a toggle that has to be looked at closely to be read at all.
Colour alone is not a signal
A separate criterion says that colour must not be the only way information is conveyed, and contrast ratios do nothing to satisfy it. A link inside a paragraph that differs from the surrounding text only by hue fails it, even when the pair measures 8:1 — because the reader who cannot distinguish those two hues has no way to tell that the words are a link. The rule that comes out of it is the familiar one: an underline, or a weight change, or some other difference that survives being seen in greyscale.
The same thinking covers the states of a form. A field whose only indication of an error is a red border is a field that says nothing to a reader who cannot see the red, so the message beside it is doing the work and the colour is a reinforcement. Charts run into it constantly: four segments distinguished by four hues, two of which are similar at small sizes, and no labels. The answer is never a fifth colour.
What the number cannot see
A ratio measures two colours. It does not know how large the type is, how heavy the face is, how much letter spacing it carries, or who is reading it. A light-weight grotesque at a small size sheds contrast as its thin stems blend into the background, and it needs noticeably more than the floor to read as comfortably as a heavier face at the same size. Where a face is light, where the text is small, or where the audience is likely to include people reading on a phone in daylight, treat a higher figure as the working target and the published minimum as the emergency exit.
That is also the honest limit of the checklist. A page can clear every threshold in the table and still be hard to read, because the criteria are floors agreed between organisations rather than descriptions of good typography. Passing them is the point at which the argument stops, not the point at which the work is finished. Where a whole family of colours has to clear the thresholds together, the Palette Generator starts from a set of ramps that already do.
Reference
The thresholds, and which one you need
| WCAG level | Normal text | Large text | UI components and graphics | What it applies to |
|---|---|---|---|---|
| AA | 4.5:1 | 3:1 | 3:1 | Body copy, form labels and links inside a sentence. The level almost every legal requirement references. |
| AAA | 7:1 | 4.5:1 | no separate rule | The same text at the enhanced level. Almost nobody meets it for body copy. |
| AA, large text only | — | 3:1 | — | Pairs between 3:1 and 4.5:1. They clear large text at 24px regular or 18.66px bold, and nothing smaller. |
| AAA, large text only | — | 4.5:1 | — | Pairs between 4.5:1 and 7:1. Comfortable on a heading, thin on the paragraph underneath it. |
| AA, non-text only | — | — | 3:1 | Input borders, focus rings, toggle states, icon buttons and the segments of a chart (WCAG 1.4.11). |
| Exempt | exempt | exempt | exempt | Logotypes, text incidental to a picture, and inactive controls. |
A pair sits in whichever band its ratio clears, and clearing large text is not clearing body text. The dashes mark the cells where the criterion does not apply at all, so a 3:1 pair and a 7:1 pair can both be called a pass without being anything like each other.
The ratio is one relative luminance divided by another, computed from linearised sRGB channels, and that is not the same thing as the brightness you perceive. Green carries most of the weighted sum and blue very little, which is why a mid-blue that looks strong on screen so often measures lower against white than the eye predicts. Read the table as bands: a pair sits in the lowest row its number clears.
The large-text column exists because thicker strokes survive less contrast. Large text means 18 point, or 24 CSS pixels, at regular weight, or 14 point, about 18.66 CSS pixels, at bold. Most arguments happen on that boundary, because it is exact: a heading set at 23 pixels is not large text, and at 24 it is, which drops everything it has to clear from 4.5:1 to 3:1.
A pass is a floor, not a target. Clearing 4.5:1 means the pair is allowed, not that the text is comfortable, and the number cannot see the type size below the threshold, the weight of the face, the letter spacing, or the eyesight of the person reading it. A page that scrapes past 4.5:1 is a page that fails for a lot of people.
Questions
Contrast, answered plainly
Why does 4.499:1 print as 4.50:1 and still fail?
Because the verdict is decided before the display is formatted. The ratio is held at full precision, all five thresholds are tested against that value, and only the readout is rounded to two decimals. If a tool rounds first, it will pass a pair that a compliance audit fails — which is the worst possible time to find out.
What counts as large text?
18.66px (14pt) and bold, or 24px (18pt) and regular. Both are CSS pixels at the browser's default zoom, measured on the rendered size rather than the size written in the stylesheet. Above that, the strokes are thick enough that the same pair reads at a lower ratio, which is why AA large is 3:1 instead of 4.5:1.
Which elements does the 3:1 rule cover?
WCAG 1.4.11 covers the parts of an interface you need in order to operate it: input borders, focus rings, toggle states, icon buttons, the segments of a chart. Text links inside a paragraph are covered by 1.4.3 instead, which is stricter. A 3:1 border on a text field is a requirement, not a polish item — without it, the field is invisible.
Are logos and disabled buttons exempt?
Yes. The success criteria exempt logotypes, incidental text inside a picture, and inactive controls, on the grounds that nothing there needs to be read. Treat that as a description of the rules rather than as permission: a disabled button nobody can read is still a broken button, and "it's our logo" is not an answer for body copy.
Can I check a colour straight off a screenshot?
No. This checker reads two hex values and nothing else — there is no code in the page that could receive an image, and no route out for one either. Sample the colour with a screen picker or your browser's dev-tools eyedropper, then paste the hex in. Taking the value by hand also forces you to decide which pixel you actually care about, which is most of the work.
My brand colour fails — what do I do?
Darken or lighten the same hue rather than swapping the colour for a different one. The fix line under the ratio walks that colour's HSL lightness one step at a time until it clears the target, leaving hue and saturation alone, so what comes back is the same brand colour in a deeper or paler version. The Use button puts it into the text field and the ratio updates with it. If the line says nothing on that hue reaches 4.5:1 against your background, the colour is not the problem — the background is.
Does bold text fix a failing contrast ratio?
No. The ratio is a property of the two colours, so it does not move when the weight changes; what changes is which threshold applies. Bold text counts as large from 14 point, about 18.66 CSS pixels, so a pair that fails at 4.5:1 can pass at 3:1 once the bold text is that big. Below that size, weight makes no difference to the arithmetic — though heavier strokes usually do read a little better.
Is 4.5:1 enough for a form placeholder?
Placeholder text is text, so AA holds it to 4.5:1, and it is the text most often set far too light. The usual causes are a grey chosen to read as a hint, which lands under the threshold, and a placeholder used as the only label a field has. A placeholder disappears the moment someone types, so anything a person needs in order to fill the field in — the format, the units, which name you want — belongs in a visible label above it.