Contrast checker

Try a pair
Interface specimen
#17231D / #F5EDDC
Preview

Legibility is a feature, not a finishing touch.

Judge the pair in context, then use the inspector to tune its role, size, and weight. Contrast is measured from the rendered solid colors.

Ratio13.93:1
UI / largePass
AA bodyPass
AAA bodyPass

Color Contrast Checker

Check a colour pair against WCAG 2.2 on real type at the size and weight you actually ship, and get the nearest colour that passes instead of a bare fail. All three thresholds are reported at once, so you can see whether a pair that misses body text still works for a heading or an icon.

AA body text
4.5:1
Large text and UI
3:1
AAA body text
7:1
Lightness steps searched for a fix
201

Step by step

How to use it

  1. 01Set the pair

    Foreground and background, in any CSS colour notation. The specimen renders live, so you are judging real type rather than two swatches side by side.

  2. 02Match the type you actually ship

    Size and weight decide which threshold applies. 18px at weight 500 is body text; 24px, or 18.66px bold, is large text and drops to 3:1.

  3. 03Read all three verdicts

    UI and large text at 3:1, AA body at 4.5:1, AAA body at 7:1 are reported together. A pair that fails body copy may be perfectly fine for a heading or an icon.

  4. 04Take the nearest passing colour

    When a pair fails, the suggested fix moves lightness only — keeping the hue and chroma of your brand colour — and stops at the first value that clears the threshold.

Worked example

Fixing a pair without losing the brand

The common case: a brand colour that misses AA on white. The fix searches lightness at 201 steps in OKLCH, holding hue and chroma fixed, and takes the smallest move that passes.

Given

Foreground
#7C93B8
Background
#FFFFFF
Target
AA body, 4.5:1

What the repair actually changes

before   #7C93B8 on #FFFFFF   3.12:1   fails AA
                                  passes nothing

search   hue and chroma held
         lightness stepped 0 -> 1 in 201 steps
         first value clearing 4.5:1 wins

after    #61779A on #FFFFFF   4.55:1   passes AA
         same hue family, darker
Before
3.12:1 · fail
After
4.55:1 · pass
Changed
lightness only

Contrast is almost entirely a lightness relationship, which is why moving only lightness usually fixes a pair while leaving it recognisably the same colour. It also explains the failure people find most surprising: two colours that look completely different — a mid blue and a mid red — can sit at nearly identical lightness and have almost no contrast at all.

Before you sign it off

What to know about contrast

The threshold depends on the type, not the colour

4.5:1 for body text, 3:1 once text is 24px, or 18.66px and bold, and 3:1 for interface components and their focus states. Checking a pair without knowing which size it will be used at answers a question you have not asked yet.

Hue difference is not contrast

The ratio is computed from relative luminance, so a saturated red on a mid green can look violently different and still fail badly. If you squint until the colours blur and the text disappears, no amount of hue separation will save it.

Ratios are the floor, not the goal

4.5:1 is the point at which the guideline stops objecting, not the point at which reading becomes comfortable. Long-form copy, small type, and low-quality screens all benefit from more, and going past AA costs you nothing but a slightly darker colour.

Disabled states and placeholders still get read

They are routinely exempted on the grounds of being inactive, and users still need to read them to know what a form wants. A greyed-out label at 2:1 is a real barrier, whatever the guideline permits.

Test the colour that will actually be behind it

Text over a photograph, a gradient, or a translucent overlay has a different ratio in every part of the frame. Check the worst region rather than the average, or put a solid scrim behind the text so there is one number to check.

WCAG 2 has known blind spots

The formula is a good tool and a rough model of perception: it is harsher on light-on-dark pairs than experience suggests and lenient on some mid-tone combinations. Treat a marginal pass on a dark theme as a prompt to look at it, not as proof.

The judgement call

Which threshold applies?

Most contrast arguments are really disagreements about which rule the element falls under.

  • Body copy, paragraphs, form labels

    4.5:1

    AA for normal text. The practical baseline for anything a reader has to work through.

  • Headings 24px and up, or 18.66px bold

    3:1

    Large text threshold. Bigger glyphs carry more of the shape, so less contrast is needed to read them.

  • Icons, borders, focus rings, chart lines

    3:1

    Non-text contrast covers anything you must perceive to use the interface.

  • Long-form reading or a low-vision audience

    7:1

    AAA. Not required in most policies, and noticeably easier on the eye for sustained reading.

  • Text over a photo or a gradient

    Check the worst spot

    The ratio varies across the image. Test the lightest region, or add a scrim so there is a single value to verify.

  • Purely decorative text or a logotype

    Exempt

    WCAG excludes logotypes and incidental text — but if a user has to read it, it is not decoration.

Reference

How the numbers are defined

Ratio range
1:1 to 21:1Identical colours give 1:1; pure black on pure white gives 21:1. Everything else falls between.
AA thresholds
4.5:1 normal · 3:1 largeLarge means 24px, or 18.66px at bold weight or heavier.
AAA thresholds
7:1 normal · 4.5:1 largeEnhanced contrast. Rarely mandated, always kinder to the reader.
Non-text contrast
3:1Applies to interface components, focus indicators, and meaningful graphics such as chart series.
Repair search
201 lightness steps in OKLCHHue and chroma are held fixed so the fix stays in the same colour family; the smallest passing move wins.
Basis
Relative luminanceContrast is a lightness relationship. Two colours of different hue but equal luminance have essentially none.

FAQ

Questions, answered plainly

What contrast ratio do I need?

4.5:1 for normal body text under WCAG AA, dropping to 3:1 once text reaches 24px or 18.66px bold. Interface components, icons, and focus indicators need 3:1. AAA raises body text to 7:1, which is worth aiming at for long-form reading even where it is not required.

Why does my colourful pair fail?

Contrast is calculated from relative luminance, not from how different two colours look. A saturated red and a mid green can be unmistakably different in hue and sit at almost the same lightness, which leaves the text barely readable. Squint at the pair: if the text disappears, so does the ratio.

How do I fix a failing pair without changing my brand colour?

Move lightness and leave hue and chroma alone — which is exactly what the suggested colour here does. It steps lightness in OKLCH and takes the first value that clears your target, so the result stays recognisably the same colour, just lighter or darker.

Do disabled buttons and placeholder text need to pass?

WCAG exempts disabled controls, and placeholders are frequently argued about. Users still have to read both to understand a form, so treating the exemption as permission to go to 2:1 creates a genuine barrier. Aim for at least 3:1 on anything carrying meaning.

Is a higher ratio always better?

Up to a point. Pure black on pure white reaches 21:1 and some readers find that glare uncomfortable for long passages, which is why many designs use a very dark grey instead. Comfortably above the threshold is the target, not the maximum.

Does this run on my machine?

Yes. Ratios, verdicts, and the suggested repair are all computed in your browser, and the share link carries only the two colours and your type settings.

Ratios, verdicts, and the suggested repair all run in your browser. Share links carry only the colours and type settings.