Color Contrast Checker

Test text and background color contrast against WCAG 2.1 AA and AAA standards. See pass/fail for normal and large text and fix accessibility issues fast.

Controls transparency - 0% is fully transparent, 100% is fully opaque

Color Tools

Color Preview & Formats

Solid (100%)

With Opacity (100%)

Color Harmony

Complementary colors are opposite each other on the color wheel, creating high contrast and vibrant looks. Perfect for making elements stand out.

Color Wheel

Click on the wheel to change hue

Saved Colors

No saved colors yet
Advertisement

Check text and background contrast against WCAG

An accessibility audit came back with a contrast failure, or a designer wants to know whether a colour is safe to put text on before the component gets built. Either way the question is the same: does this foreground on this background clear the ratio the standard asks for, and if not, what is the smallest change that fixes it?

This page answers that for a colour you choose. Pick or load a colour and the Text & Background Combinations panel shows it as a background with white text and with black text, each with its measured contrast ratio and a verdict badge, alongside pairings drawn from its harmony colours. The list is sorted best-readability-first, so the top of it is the pairing you should probably ship. A font selector re-renders every sample in a different typeface, which is more useful than it sounds: a ratio that is comfortable in a sturdy sans-serif can be marginal in a thin geometric one at the same number.

Be clear about the shape of the tool before you rely on it. This is not a two-box form where you type an arbitrary foreground and an arbitrary background. It evaluates the current colour against white, against black, and against the other colours in its harmony set. To test a specific pair, load one of the two colours — append ?color= plus its hex with the # written as %23, so ?color=%23767676 — and read its row. Everything runs in your browser; no colours, screenshots or page URLs are sent anywhere.

What the contrast ratio actually measures

The WCAG contrast ratio is not a measure of how different two colours look. It compares only their relative luminance — how much light each one emits — and is deliberately blind to hue. Two colours can be violently different and still fail; a red and a green of similar luminance will score badly, which is exactly the pairing that also fails for colour-blind readers.

The calculation linearises each sRGB channel, weights the three channels, and compares the two results with a small constant added to both:

  • Each channel is divided by 255 and passed through the sRGB transfer function, so the value reflects emitted light rather than the encoded number.
  • The weights are 0.2126 for red, 0.7152 for green and 0.0722 for blue. Green dominates because human vision is most sensitive to it; blue contributes very little.
  • The ratio is (lighter + 0.05) ÷ (darker + 0.05). The 0.05 term models ambient light reflecting off the screen, and it is what keeps the scale finite.

The consequence of those weights is worth internalising: a saturated blue is far darker than a saturated yellow, even when a colour picker calls them equally light. Pure blue on white passes comfortably; pure green on white does not come close. The scale runs from 1:1, two identical colours, to 21:1, black on white.

The thresholds

What you are colouringLevel AALevel AAA
Normal-size text4.5:17:1
Large text3:14.5:1
UI components and graphical objects3:1no additional requirement
Disabled controls and pure decorationexemptexempt
Logotypesexemptexempt

AA is the level most organisations commit to and the level referenced by most procurement and regulatory requirements. AAA is a stretch target that is rarely achievable across a whole interface, and the standard itself does not expect it to be met site-wide.

The badges in the combinations list are keyed to AA. A pairing at or above 4.5:1 is marked as usable at all text sizes; between 3:1 and 4.5:1 it is marked large-text-only; below 3:1 it is not recommended. The numeric ratio is printed next to every badge, so if you are chasing AAA, compare that number against 7:1 yourself.

What counts as large text

"Large" is defined by size and weight, not by which heading tag you used. It means at least 18 point, or at least 14 point when bold. In CSS pixels at the default browser setting, that is roughly 24px, or about 18.66px when bold.

Two mistakes follow from this. The first is treating every <h2> as large text: a heading styled down to 20px regular is normal text and needs 4.5:1. The second is forgetting that users can change the base font size, and a layout that only clears 3:1 because its text is nominally 24px becomes non-conforming the moment a relative unit resolves smaller than you assumed. If a value is anywhere near a boundary, hold it to the normal-text threshold and stop worrying about it.

The 3:1 rule for interface parts

Contrast requirements are not only about text. Non-text content that carries meaning needs 3:1 against whatever is adjacent to it, and this is where most real audits find their failures, because the visual language of modern interfaces is full of pale grey:

  • The border or underline of a text input, if that boundary is the only thing showing where the field is.
  • Focus indicators. A focus ring must be distinguishable against both the component and the page behind it.
  • Toggle switches, checkboxes and radio buttons — the shape that signals state, not just the label.
  • Icons that convey information rather than decorate. A warning triangle needs contrast; a flourish next to a heading does not.
  • Chart segments, sparkline strokes, and the boundaries between adjacent data colours where reading the chart depends on telling them apart.

Note that this is contrast against adjacent colour, not against the page background. A grey border between a white card and a white page is measured against white; the same border against a tinted panel is a different calculation.

Fixing a failing pair: move lightness, not hue

When a brand colour fails, the temptation is to nudge the hue until the number goes up. Resist it. Rotating hue changes which colour it is — the part your brand actually owns — and because of the channel weights the effect on contrast is erratic. Here is the same colour at a fixed HSL saturation and lightness, rotated through six hues, measured against white:

HueHex at s 34%, l 47%Ratio on white
0 (red)#A14F4F5.60:1
60 (yellow)#A1A14F2.72:1
113 (green)#59A14F3.16:1
180 (cyan)#4FA1A13.02:1
240 (blue)#4F4FA17.08:1
300 (magenta)#A14FA15.06:1

Identical lightness on paper, and the ratio swings from failing normal text to clearing AAA. That is the clearest demonstration that HSL lightness is not luminance, and why hue-nudging is guesswork.

Lightness, by contrast, moves the ratio predictably and in one direction, and it keeps the colour recognisable. The Lighten and Darken buttons on this page step HSL lightness by ten points, holding hue and saturation. Starting from that green:

  • #59A14F on white is 3.16:1 — large text only, fails for body copy.
  • One press of Darken gives #467E3E at 4.87:1 — now passes AA at every text size.
  • A second press gives #335C2D at 7.75:1 — clears AAA for normal text as well.

One step was enough. The colour is still obviously the same green, which is the argument to take back to whoever owns the brand: nobody is being asked to change the palette, only to reserve the light tint for backgrounds and fills and use a darker step for text. If you need a full set of tints and shades to work from, the colour palette generator produces one from a base colour.

The mistakes that survive a passing check

A green tick on the default state is not the same as an accessible component. These are the gaps that a single measurement misses.

  • Only the resting state was tested. Hover, focus, active, visited, disabled, selected, and the placeholder inside an input all have their own colours, and hover states in particular tend to be a lightened variant that quietly drops below the threshold. Disabled text is exempt from the requirement, but that exemption is often stretched to cover controls that are not really disabled.
  • Dark mode was assumed to be symmetrical. Inverting a palette does not preserve ratios — the same accent that passed on white will usually fail on near-black, because the luminance gap is not symmetrical around the middle. Every pair has to be measured again in the other theme.
  • Text sits on an image or a gradient. There is no single ratio to compute, because the background changes under the text. Either measure the worst pixel behind any glyph rather than the average, or stop the problem at the source with a solid plate or a scrim behind the text block so there is a fixed colour to measure.
  • Opacity was ignored. Text at 60% alpha is not the colour you specified; it composites with whatever is behind it, and the ratio must be computed on the composited result. Combinations on this page are evaluated at full opacity for exactly that reason. If your design uses translucent text, work out the flattened colour first and test that.
  • The check ran on the wrong background. Cards, banners, sticky headers and modals each introduce a new background. A body colour that passes against the page can fail against a tinted card two levels in.
  • Colour was the only signal. Contrast and colour-independence are separate requirements. A red field label at 8:1 still fails a reader who cannot see red as different from the text around it unless an icon or wording carries the same message.

What the ratio does not tell you

The formula is a model, and a coarse one. It takes no account of font weight, letterform, size beyond the two-bucket large/normal split, or the surrounding page, so hairline type at exactly 4.5:1 can still be genuinely hard to read while a heavy face at the same number is comfortable. It also behaves differently at the two ends of the scale, which is why light-on-dark interfaces that pass on paper sometimes look glaring in practice. Work on a successor model for WCAG 3 addresses some of this, but it is not what conformance is measured against today. Treat the threshold as a floor to clear rather than a target to sit exactly on, and look at the rendered sample before you sign it off — which is what the preview tiles on this page are for.

Frequently Asked Questions

What is a good contrast ratio for text?+

For normal body text, aim for at least 4.5:1 to meet WCAG AA, and 7:1 to meet the stricter AAA level. Large text (18pt regular or 14pt bold and above) can pass AA at 3:1. Higher ratios are better for readability.

What is the difference between WCAG AA and AAA?+

AA is the standard most sites target and is widely referenced by accessibility laws; it requires 4.5:1 for normal text. AAA is an enhanced level requiring 7:1 for normal text, used when maximum legibility is a priority. AAA is not expected for all content.

How is contrast ratio calculated?+

It compares the relative luminance of the two colors. Each color is converted to a luminance value weighted for how the eye perceives red, green, and blue, then the lighter and darker values are combined into a ratio from 1:1 to 21:1.

My colors fail — how do I fix them?+

Adjust lightness rather than saturation: make the text darker or the background lighter until the ratio clears the threshold. Increasing saturation alone usually has little effect on contrast because the ratio depends mainly on luminance difference.

Does contrast apply to every element on the page?+

It applies to text and to meaningful user-interface components and graphics needed to understand the content. Purely decorative images, disabled controls, and logos are exempt, although good contrast still improves usability.

This tool is provided for informational and educational purposes only. All processing happens in your browser — no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results.