How to test color contrast against WCAG 2.2

The contrast ratios WCAG requires for text and interface parts, how the ratio is calculated, the cases tools miss, and how to check a whole page.

Low contrast is the most common accessibility failure on the web, and one of the easiest to fix once you can see it. Here is what the rules ask for and how to check a page against them.

The ratios WCAG asks for

WhatLevel AALevel AAACriterion
Normal text4.5 : 17 : 11.4.3, 1.4.6
Large text (24 px, or 18.66 px bold)3 : 14.5 : 11.4.3, 1.4.6
Icons, input borders, focus indicators3 : 1n/a1.4.11

Disabled controls, decorative text and logos are exempt. Placeholder text is not: if it carries information, it needs 4.5 : 1 like any other text.

How the ratio is calculated

Each colour is converted to its relative luminance, a value from 0 (black) to 1 (white) that weights green most and blue least, the way our eyes do. The ratio is the lighter luminance plus 0.05, divided by the darker plus 0.05:

const channel = (value) => {
  const c = value / 255;
  return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
};
const luminance = ([r, g, b]) => 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
const contrast = (a, b) => {
  const [light, dark] = [luminance(a), luminance(b)].sort((x, y) => y - x);
  return (light + 0.05) / (dark + 0.05);
};
contrast([118, 118, 118], [255, 255, 255]); // 4.54: #767676 on white just passes AA

The cases that slip through

  • Text on images and gradients. The contrast changes across the image; check the worst spot, and add an overlay if needed.
  • Opacity. Text at opacity: 0.6 is lighter than its colour value says.
  • States. Hover, focus, visited and disabled colours each need checking.
  • Dark mode. A palette that passes in light mode often fails in dark, especially greys and brand colours.
  • Different layouts. On a phone the same heading may sit on the image instead of beside it.

Check a whole page, on every screen

Chrome DevTools shows the ratio of one element in its colour picker, and an automated audit such as axe-core finds most failures. Panescope runs both ideas on the live page: the contrast overlay marks every text below AA or AAA where it is, on every screen at once, and the WCAG 2.2 audit lists the failures with the screens they affect. Hover any text with Inspect to see its exact ratio.

Panescope · panescope.com/demo
Contrast overlay marking text below AA on the live page
Try it on your own site

Panescope is free for up to 3 screens. Pro for 3 days, no card needed.

Add to Chrome

Test every screen before your users do.

Free to start. Pro for 3 days without a card.