WCAG Contrast Checker
Compute the contrast ratio between two colours and check it against WCAG AA and AAA, for text and interface elements. Suggests a fixed colour without losing the hue.
Accepts #hex, rgb(), hsl() and CSS names.
Contrast ratio
1.83:1
Aa
The quick brown fox jumps over the lazy dog.
Fix the colour
It only adjusts lightness and keeps hue and saturation, so the colour stays the one from your brand.
Preview
Large text (24px)
The quick brown fox jumps over the lazy dog.
Normal text (16px)
The quick brown fox jumps over the lazy dog.
Small text (13px)
The quick brown fox jumps over the lazy dog.
What counts as “large text”
It is not a visual impression, it is a concrete threshold: 18 pt (24 px) at normal weight, or 14 pt (18.66 px) bold. Below that the minimum is 4.5:1 even if the text looks big. It is the mistake that produces the most false passes.
What this tool does
It measures the contrast ratio between a text colour and a background colour, and tells you at once whether it meets the five WCAG 2.2 thresholds that matter: AA and AAA for normal and large text, plus the non-text one almost nobody checks.
If it fails, it proposes a corrected colour keeping the hue and the saturation: it adjusts lightness only, so the result is still your brand colour, just a little darker or lighter.
It accepts #hex, rgb(), hsl() and CSS names, and resolves transparency for you.
How to use it
- Set the text colour and the background colour, with the picker or by typing them.
- Read the ratio and the five results.
- If something fails, press the fix button for the level you need.
- Check the preview: the same text at 24, 16 and 13 pixels.
The thresholds, and which one applies to you
| Element | AA | AAA |
|---|---|---|
| Normal text | 4.5:1 | 7:1 |
| Large text | 3:1 | 4.5:1 |
| Non-text elements | 3:1 | — |
AA is the one regulations demand. The European accessibility directive, the US Section 508 and most national laws point at WCAG level AA. AAA is meant for specific contexts and the standard itself says it is not required as a general requirement for a whole site.
The forgotten threshold: 1.4.11
Criterion 1.4.11 Non-text Contrast asks for 3:1 on things that are not text but carry information:
- The border of a form field against the page background. An input with an
#e5e5e5border on white gives 1.3:1 and is invisible to many people. - Icons that mean something (a bin, a warning, a check).
- The lines and bars of a chart, which is where it is broken most often.
- The keyboard focus indicator.
It does not apply to pure decoration or to logos. But a design that passes AA on all its text and fails here is still inaccessible.
What counts as “large text”
This is the number one cause of false passes, because it sounds like a visual criterion and it is a number:
- 18 pt = 24 px at normal weight
- 14 pt = 18.66 px in bold
A 20 px heading at normal weight is not large text: it needs 4.5:1, not 3:1. The confusion arises because on screen it clearly looks bigger than body copy, but the threshold does not care about that.
Practical rule: when in doubt, apply 4.5:1. Passing by too much has never failed an audit.
Why two very different colours can fail
WCAG contrast does not measure colour difference, it measures brightness difference. And brightness is not shared equally across the three channels:
| Channel | Weight in luminance |
|---|---|
| Green | 71.52 % |
| Red | 21.26 % |
| Blue | 7.22 % |
Blue contributes less than a tenth of perceived brightness. That explains two surprising things:
- Blue on black almost always fails.
#0000ffon#000000gives 2.44:1, even though it is perfectly distinguishable on a good screen. For someone with low vision, or anyone with their phone in direct sunlight, that hue difference is not enough. - Yellow on white is worse than it looks. Yellow has red and green at maximum, so it is nearly as luminous as white:
#ffff00on#ffffffgives 1.07:1.
The underlying reason is that contrast is designed to work even when colour is not perceived: colour blindness, greyscale, poor screens, direct light.
And gamma, which is where home-made implementations break
To get luminance it is not enough to weight the R, G and B values straight out of the hex. You must first undo the sRGB gamma correction on each channel, because a colour’s values are not linear with respect to the light the screen emits. A #808080 does not emit half the light of #ffffff: it emits 21.6 %.
Skipping that step — averaging channels, or weighting them without linearising — produces numbers that look reasonable and are wrong, which is the worst thing that can happen in an accessibility check.
How to fix without losing the brand
When a corporate colour fails, the reflex is to change it. It is almost never necessary.
Contrast depends on lightness, not on hue or saturation. Moving lightness alone in HSL reaches the threshold while keeping the identity: a brand blue is still the same blue, just a notch darker. That is what the fix buttons on this page do, and why they tell you whether the adjustment goes up or down.
Two honest caveats:
- Sometimes the problem is the background. Over a mid grey (
#808080) no text colour reaches 7:1, because neither pure black nor pure white gets there from that base. When the tool proposes no fix, that is why. - The brand colour can stay where it is if you use it only on large or decorative elements and use the corrected variant for small text. That is what most serious design systems do: one brand colour and an “accessible” version of it for text.
Transparency has to be resolved first
WCAG works with opaque colours. If your text is rgba(0,0,0,0.6), it has no contrast of its own: it has the contrast of the colour that results from compositing it over whatever is behind.
The practical consequence is that the same value can pass and fail depending on where you put it. A translucent grey that works on a white card can fail over an image. This tool composites automatically and shows you the two opaque colours it is really measuring, so you know what you are approving.
Frequently asked questions
What contrast ratio do I need to meet WCAG?
It depends on what the element is and which level you are aiming for. For normal text, level AA requires 4.5:1, which is the minimum most accessibility regulations demand. For large text it drops to 3:1. Level AAA rises to 7:1 for normal text and 4.5:1 for large. And there is a fourth threshold almost nobody checks, from criterion 1.4.11: non-text elements — input borders, icons that carry information, chart lines — need 3:1 against whatever sits next to them.
What counts as “large text” in WCAG?
It is not a visual impression but a concrete threshold: 18 points, which is 24 pixels, at normal weight; or 14 points, which is 18.66 pixels, in bold. Below that the minimum is still 4.5:1 even if the text looks big on screen. It is the mistake that produces the most false passes: someone measures a 20px heading, applies the 3:1 threshold because "it is a heading", and that size actually requires 4.5:1.
Why do two colours that look different fail the contrast check?
Because WCAG contrast does not measure colour difference but luminance difference, and luminance is not shared equally across channels: green contributes 72 % of perceived brightness, red 21 % and blue only 7 %. That is why blue text on black fails easily even though it is clearly distinguishable, and why two very different hues with similar brightness can produce a ratio close to 1. A user with low vision, or a screen in bright sunlight, needs the brightness difference, not the hue one.
How is the contrast ratio calculated?
You compute each colour's relative luminance and apply the formula (L1 + 0.05) / (L2 + 0.05), with L1 the lighter one. The result runs from 1:1 (identical colours) to 21:1 (black on white). What matters is the step before: to obtain luminance you must undo the sRGB gamma correction on each channel before weighting them — averaging R, G and B is not enough. Skipping that step gives plausible, wrong numbers.
What if my brand colour does not pass the contrast check?
You rarely need a different colour; adjusting its lightness is usually enough. The fix this tool proposes moves only the lightness and keeps hue and saturation, so the result is still recognisably the same brand colour, just a little darker or lighter. If not even the extreme of that hue reaches the threshold, the problem is not the text but the background: over a mid grey no text colour can reach 7:1.
How does transparency affect contrast?
WCAG does not allow transparency in the calculation: it requires resolved colours. If your text or background has alpha, they must first be composited over whatever is behind and the resulting colour measured. This tool does that automatically and shows you the two opaque values actually being measured. The practical consequence is that the same `rgba()` can pass over one background and fail over another.
Reviews & ratings
No reviews yet. Be the first to leave one!
Related tools
Others from the catalogue that pair well with this one.