Skip to contentAltstamp
Menu

Colour contrast checker

Enter a text colour and a background, and this check gives the contrast ratio WCAG uses, worked out with the formula in the WCAG 2.2 text, with a Pass or Fail for normal text, large text and the borders and icons that mark a control. It runs in your browser and sends nothing anywhere.

Line drawing of a black and a grey swatch under a magnifier whose lens is ringed in orange

What WCAG asks

  • 1.4.3Contrast (Minimum)AA
  • 1.4.11Non-text ContrastAA
  • 1.4.6Contrast (Enhanced)AAA

What it checks

The check takes one text colour and one background colour and works out the contrast ratio between them, the single number WCAG uses for contrast. It then holds that number against the five thresholds a website meets or misses: normal and large text at Level AA, the same two at Level AAA, and the 3:1 that buttons, input borders and icons need.

"Large-scale" text is at least 18 point, or 14 point bold. W3C's Understanding note puts that at about 24px and 18.5px (1pt = 1.333px). Most body copy, menus, form labels and button words are smaller than that, so they need the normal-text figure. If you are unsure about a font, our guide to fonts and what WCAG actually asks covers size, weight and thin typefaces.

It reads flat, solid colours. Text laid over a photo or a gradient has no single background, so test it against the lightest part the text crosses; W3C lists low-contrast background images as a known failure of 1.4.3 (F83). Take the colours from your stylesheet or theme settings rather than an eyedropper on a screenshot: W3C's note on this criterion warns that anti-aliasing can draw thin text fainter than its real colour, so the code value is the one to test. Nothing you type leaves your browser.

What WCAG asks

What WCAG asks: 1.4.3 Contrast (Minimum), Level AA

The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:

  • Large Text Large-scale text and images of large-scale text have a contrast ratio of at least 3:1;
  • Incidental Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement.
  • Logotypes Text that is part of a logo or brand name has no contrast requirement.

Two neighbours sit beside it. 1.4.11 Non-text Contrast (Level AA) asks for at least 3:1 against adjacent colours for the parts that let someone find a control and its state (an input's border, a checkbox, a focus ring) and for parts of graphics needed to understand the content. 1.4.6 Contrast (Enhanced) is Level AAA: at least 7:1 for text, 4.5:1 for large text. A site that meets WCAG 2.1 AA or 2.2 AA does not need the AAA rows; they are shown because some brands aim higher, as this site does for its body text.

The 4.5 is not arbitrary. W3C starts from 3:1, the minimum for standard vision in the ISO and ANSI standards it cites, and multiplies by about 1.5 for the contrast sensitivity lost at 20/40 vision; 7:1 follows the same logic for 20/80. The same note says the rule covers placeholder text in form fields and text that appears on hover or keyboard focus, which is where many sites slip. The longer walk-through is in colour contrast requirements explained.

How the ratio is worked out

Each colour becomes a relative luminance, from 0 for black to 1 for white: every channel is divided by 255, linearised (a value at or below 0.04045 is divided by 12.92, anything above becomes ((c + 0.055) / 1.055) to the power 2.4), then weighted 0.2126 for red, 0.7152 for green and 0.0722 for blue. The ratio is (L1 + 0.05) / (L2 + 0.05), with the lighter colour on top, so it runs from 1:1 to 21:1. Green carries most of the weight, which is why a pale green and a pale blue of similar look can score very differently.

Ratios are thresholds and are not rounded: 4.499:1 does not meet 4.5:1. This check compares the unrounded value and shows two decimals, cut down instead of rounded whenever rounding would carry the figure over a line, so the number on screen never looks like a pass that the verdict calls a fail.

Pairs this check was tested against, worked out by the same code
PairRatioNormal text AA
#000000 on #ffffffBlack on white, the top of the scale21.00:1Pass
#171717 on #ffffffThis page's body text17.93:1Pass
#595959 on #ffffffThis page's quieter text, just over 7:17.00:1Pass
#767676 on #ffffffThe lightest neutral grey that passes 4.5:1 on white4.54:1Pass
#777777 on #ffffffOne step lighter: fails normal text4.48:1Fail
#ea580c on #ffffffThis site's orange focus ring, never used for text3.56:1Fail
#949494 on #ffffffW3C's own example of a 3:1 focus indicator3.03:1Fail
#999999 on #ffffffA common light grey for dates and captions2.85:1Fail

What a fail usually looks like

Contrast fails are rarely black text on a dark ground. They are pale, tasteful choices that looked fine on the designer's screen. These five are the usual ones.

  • Quiet grey text

    Dates, captions, footer links, prices struck through, "posted by" lines. A theme's light grey such as #999999 on white is 2.85:1, which fails even the large-text line. The near miss is more common still: #777777 is 4.48:1, the pair this check opens with.

  • Placeholder text doing a label's job

    Browsers draw placeholder text pale, and W3C says 1.4.3 applies to it. A form that relies on "Your email" inside the box fails twice: the contrast and the missing label. The fix for both is in accessible forms.

  • White words on a bright brand button

    White on this site's own ring orange, #EA580C, is 3.56:1: enough for a 3:1 border or icon and for large text, not for a 16px "Book now". That is why the orange here draws focus rings and never text.

  • Input borders you can barely see

    A #DDDDDD field border on white is 1.36:1, well under the 3:1 that 1.4.11 asks of the edge that shows where to type. The same applies to a focus indicator drawn in a pale tint.

  • States nobody tested

    Text that fades on hover, a menu item that turns pale when focused, a sale badge over a product photo. Each state is its own pair: test the colours of every state, not only the resting one. A link that differs from body text by colour alone is a separate rule, use of colour.

How to fix a fail

On a light background, darken the text. Keep the hue and step the colour toward black until the ratio clears the line; the check does this for you and offers the nearest shade that reaches 4.5:1 (for #777777 on white that is #767676, one step darker). Never fix it by lightening text that sits on a light ground: that lowers the ratio.

Change the colour once, where it is defined: the theme setting, the CSS variable, the brand token. A fix made page by page comes back with the next template. Then re-test the hover, focus and disabled states that use the same token, and keep any lighter shade for text that is really large at the size it is delivered.

A fix lives in your own code

A widget that recolours the page on the visitor's side leaves your stylesheet as it was. Our guide to accessibility overlays explains why that does not make a site conform.

To check a whole palette at once rather than pair by pair, use the accessible colour palette check. Contrast is one line of the WCAG 2.2 AA checklist, and if you want a scanner to sweep every page for flat-colour pairs like these, the testing tools comparison sets the options side by side.