View all services
Talk to QA Advisor
Free tool · Accessibility

Colour contrast checker for WCAG 2.2

Enter a text and background colour in any CSS format and see the exact contrast ratio, unrounded, with pass or fail for every WCAG 2.2 level. Failing pairs come with the nearest colours that pass, ready to apply or paste into a bug report.

Colour contrast checker

Check the contrast of two colours against WCAG 2.2, get the nearest colours that pass, and export the result as a bug report.

Examples

#777777 · rgb(119, 119, 119) · hsl(0, 0%, 47%)

The ratio is the same either way.

#ffffff · rgb(255, 255, 255) · hsl(0, 0%, 100%)

Hex (3, 4, 6 or 8 digits), rgb(), rgba(), hsl(), hsla() or a CSS colour name. A translucent text colour is painted over the background first, and a translucent background over white.

Contrast ratio

4.47:1

2 of 5 checks pass. Fails AA for normal text. Passes only for large text and for UI components and graphics.

  • FailAA, normal text (SC 1.4.3, AA). Needs 4.5:1. Body text and anything below the large-text size.
  • PassAA, large text (SC 1.4.3, AA). Needs 3:1. At least 18pt (24px), or 14pt (about 18.67px) bold.
  • FailAAA, normal text (SC 1.4.6, AAA). Needs 7:1. Body text, enhanced level.
  • FailAAA, large text (SC 1.4.6, AAA). Needs 4.5:1. Large text, enhanced level.
  • PassNon-text: UI components and graphics (SC 1.4.11, AA). Needs 3:1. Input borders, icons, focus indicators, chart lines.

Preview

A visual preview of the two colours as normal text, large text, a button and an input border. The outcome for each is listed above.

Nearest passing colours

Lightness changed, hue and saturation kept, so the colour still reads as the same brand colour. Every suggestion is checked after rounding to hex.

Nearest text and background colours that reach each contrast target
TargetChange the text colourChange the background
AA normal text4.5:1
#7676764.54:1
#0606064.52:1
AAA normal text7:1
#5959597.00:1
Not reachable with this hue. Change the text colour instead.
Large text and UI3:1Already passesAlready passes
Export

A Markdown defect for Jira, GitHub or Azure DevOps, with every level and the suggested fixes.

Palette checker

Paste brand or design system colours to see every pair at once: which can carry body text, which only large text or UI, and which are decoration only.

One per line, or separated by commas. An optional name goes first, such as “Primary: #31423d”. Duplicates are dropped and translucent colours are flattened onto white.

21 pairs. 8 pass AA for normal text, 4 only for large text and UI, and 9 fail.

Contrast ratio of every pair of palette colours, with the highest level each pair passes
ColourInkBrand greenSageMistCreamWhiteAlert red
InkSame1.63Fail4.46Large / UI9.33AAA15.91AAA17.40AAA3.20Large / UI
Brand green1.63FailSame2.72Fail5.69AA9.71AAA10.62AAA1.95Fail
Sage4.46Large / UI2.72FailSame2.08Fail3.56Large / UI3.89Large / UI1.39Fail
Mist9.33AAA5.69AA2.08FailSame1.70Fail1.86Fail2.91Fail
Cream15.91AAA9.71AAA3.56Large / UI1.70FailSame1.09Fail4.97AA
White17.40AAA10.62AAA3.89Large / UI1.86Fail1.09FailSame5.43AA
Alert red3.20Large / UI1.95Fail1.39Fail2.91Fail4.97AA5.43AASame

AAA: 7:1, any text. AA: 4.5:1, any text at AA. Large / UI: 3:1, large text, UI components and graphics only. Fail: below 3:1.

Export

Every pair with its ratio and the levels it passes, highest contrast first.

Ready
How to use

How to use the Colour contrast checker

  1. 1Enter the text colour and the background colour as hex, rgb(), hsl() or a CSS colour name, or pick them with the colour pickers. The example opens on #777777 on white, a grey that looks acceptable and fails.
  2. 2Read the ratio and the five checks: normal and large text at AA and AAA, and non-text contrast for UI components and graphics. Each one says pass or fail in words.
  3. 3If a check fails, apply the nearest passing text colour or background. Only the lightness changes, so the colour stays recognisably the same.
  4. 4Export the result as a Markdown bug report or CSV, or paste your whole palette into the palette checker to see which pairs can carry text.

How the contrast ratio is calculated

WCAG compares the relative luminance of the two colours: how bright each one is, on a scale from 0 for black to 1 for white. Each sRGB channel is first converted from its gamma-encoded value to linear light, then the three channels are weighted by how sensitive the eye is to each. Green counts for most of the result and blue for very little, which is why a saturated blue can carry white text that a yellow of the same lightness cannot.

The ratio runs from 1:1, for two identical colours, to 21:1, for black on white. The result is compared with each threshold without rounding: the Understanding documents give 4.499:1 as an example that does not meet 4.5:1. This checker therefore truncates the displayed value to two decimals, so a ratio just below a threshold never displays as meeting it.

  • Linearise each channel

    c = value / 255 if c <= 0.04045: c / 12.92 else: ((c + 0.055) / 1.055) ^ 2.4

    The 0.04045 threshold is the one in the current WCAG 2.2 text. Versions before May 2021 printed 0.03928, taken from an older sRGB document. The W3C notes the change has no practical effect on the results.

  • Relative luminance

    L = 0.2126 × R + 0.7152 × G + 0.0722 × B

    R, G and B are the linearised channels. White has a luminance of 1 and black of 0.

  • Contrast ratio

    (L1 + 0.05) / (L2 + 0.05)

    L1 is the lighter colour and L2 the darker, so the order you enter the colours in does not change the ratio.

  • Translucent colours

    seen = alpha × colour + (1 − alpha) × background

    What users see is the colour after blending. A translucent text colour is painted over the background, and a translucent background over white, then rounded to whole 8-bit values as the browser and axe-core do.

What counts as large text

WCAG defines large-scale text as at least 18 point, or at least 14 point if bold. Large text needs 3:1 at AA and 4.5:1 at AAA, instead of 4.5:1 and 7:1. In CSS, 1pt is 4/3 of a pixel, so 18pt is 24px and 14pt is about 18.67px. The Understanding document rounds these to approximately 24px and 18.5px, and WCAG notes that for many body fonts they are roughly 1.5em and 1.2em of the default size.

The size that counts is the size when the content is delivered, not what a user gets by zooming. A 16px heading does not become large text because people can enlarge it. Font weight matters only at the bold threshold: 18.67px at a weight of 400 is normal text. WCAG also warns that fonts with very thin strokes or unusual letterforms are harder to read at lower contrast, so treat the large-text allowance with care for light weights.

What is exempt, and what is not

SC 1.4.3 and 1.4.6 list two exceptions. Incidental text has no contrast requirement: text that is part of an inactive user interface component, such as a disabled button, text that is pure decoration, text that is not visible to anyone, and text that is part of a picture containing significant other visual content, such as a street sign in a photograph. Logotypes are the second: text that is part of a logo or brand name.

Images of text are not exempt. A banner with words baked into the image must meet the same ratio as live text, and is usually harder to fix. Placeholder text is not exempt either: the Understanding document lists it explicitly, along with text that appears on hover or keyboard focus. A disabled control is exempt, but if users cannot tell it is disabled rather than unreadable, that is worth raising as a usability issue even though it is not a WCAG failure.

What SC 1.4.11 non-text contrast covers

SC 1.4.11, at level AA, asks for 3:1 against adjacent colours for two things. The first is the visual information needed to identify user interface components and their states: the border of an input when nothing else shows where it is, the check in a checkbox, the thumb of a toggle, and the focus indicator. The second is the parts of graphics needed to understand the content, such as the lines of a chart or an icon that carries meaning without a text label.

It does not cover text: the label on a button is text, so it falls under 1.4.3. It exempts inactive components, components whose appearance is set by the browser and not changed by the author, and graphics whose particular presentation is essential. The Understanding document also says a control does not need a visible border at all if other visible content identifies it, and that extra styling shown only on hover does not need to meet 3:1, provided it does not reduce the contrast of the component itself.

Testing contrast in real states

A design file shows one state. The product has many, and contrast failures hide in the ones nobody screenshots. Check every colour pair a user can actually see, not just the default.

  • Hover, focus, active and selected

    Text that changes colour on hover or focus must still meet 4.5:1 in that state, and the focus indicator must meet 3:1 against what surrounds it.

  • Placeholder and helper text

    Light grey placeholders are among the most common failures. They are covered by 1.4.3 like any other text.

  • Text over images and gradients

    Measure against the part of the image or gradient that gives the lowest contrast with the text, usually the lightest area under light text. A scrim or overlay behind the text is the usual fix.

  • Dark mode and themes

    Every theme is a separate set of colour pairs. A grey that passes on white often fails on a dark surface, and brand colours rarely work unchanged on both.

  • Opacity and translucent overlays

    Text at 60% opacity is a different colour on every background it sits on. Enter the rgba() value here with each real background.

  • Error, success and status colours

    Red error text on white and green success text on pale green are frequent failures, and the message is often the most important text on the screen.

What a contrast ratio cannot tell you

The ratio compares luminance only. It says nothing about whether information is conveyed by colour alone, which SC 1.4.1 Use of Color covers: a red error border with no icon or message can pass 1.4.11 and still fail 1.4.1. Two colours with a good ratio can also be hard to tell apart for someone with a colour vision deficiency if the difference that matters to the design is hue.

It cannot see rendering either. Thin fonts, small sizes and anti-aliasing can make text fainter on screen than its specified colour suggests, which the WCAG definition of contrast ratio acknowledges. A checker measures the colours you give it; an audit has to find every place those colours meet, in every state, and confirm the page passes in a real browser with automated tools such as axe-core and manual review.

QAble service

Accessibility audit

QAble audits websites and apps against WCAG 2.2 with automated scans and manual testing by keyboard and screen reader, and reports every issue with its success criterion and a fix.

Explore the service
FAQ

Frequently asked questions

What contrast ratio does WCAG 2.2 require?

At level AA, 4.5:1 for normal text and 3:1 for large text (SC 1.4.3), and 3:1 for user interface components and meaningful graphics (SC 1.4.11). At level AAA, 7:1 for normal text and 4.5:1 for large text (SC 1.4.6). Most accessibility policies and laws that reference WCAG ask for level AA.

Is #767676 on white accessible?

Yes, for text at level AA. #767676 on #ffffff is 4.54:1, which meets 4.5:1. It is the lightest neutral grey that does: #777777 on white is 4.47:1 and fails. It does not meet AAA for normal text, which needs 7:1; #595959 is the lightest grey that does.

Why does this checker show 4.49:1 when another tool shows 4.5:1?

Because WCAG says the ratio must not be rounded before comparing it with the threshold, so a pair at 4.497:1 fails 4.5:1. This checker truncates the displayed value to two decimals, so a failing ratio never displays as a passing one. A tool that rounds may show 4.50:1 for the same failing pair.

Does placeholder text need to meet contrast requirements?

Yes. The Understanding document for SC 1.4.3 names placeholder text as covered, so it needs 4.5:1 like other normal text. Text that appears on hover or keyboard focus is covered too.

Do disabled buttons need enough contrast?

No. Text in an inactive user interface component is incidental under SC 1.4.3, and inactive components are excluded from SC 1.4.11. Users still need to recognise that the control exists and is unavailable, so very faint disabled states are worth reporting as a usability issue.

Are the colours I enter sent anywhere?

No. Everything is calculated in your browser and nothing is sent to a server, so unreleased brand colours and client palettes stay on your machine.

Need every colour pair checked for you?

QAble accessibility testers check contrast in every state and theme, alongside keyboard, screen reader and WCAG 2.2 conformance, before your users find the gaps.

Talk to QA Advisor