Home / Blog / Check color contrast

How to Check Color Contrast on Any Website

Published August 12, 2026 · Updated August 12, 2026 · 7 min read · by the CSS DNA team

Quick answer: WCAG 2.2 Level AA needs 4.5:1 for normal text, 3:1 for large text (24px+, or 18.66px+ bold) and 3:1 for UI components. Measure it on the rendered page with an eyedropper, not from CSS values — because the moment text sits on an image, a gradient or a translucent scrim, the declared background is not the real one.

The numbers, in one table

WhatAA (SC 1.4.3)AAA (SC 1.4.6)
Normal text (under 24px)4.5:17:1
Large text (24px+, or 18.66px+ bold)3:14.5:1
UI components, focus rings, icons (SC 1.4.11)3:1
Incidental, decorative or disabled elementsExemptExempt

Two of those rows trip people up. Large text is defined by rendered size, so a 20px heading is still “normal text” and needs the full 4.5:1. And SC 1.4.11 is the one most teams have never read: the border of an input, the edge of a toggle and the focus ring all need 3:1 against their surroundings, independently of any text.

Method 1: the DevTools color picker

Inspect an element, click the color swatch next to color in the Styles pane, and the picker shows the contrast ratio against the computed background, with AA and AAA marked. Chrome draws a line across the picker showing exactly which colors would pass — useful when you are choosing a replacement rather than just grading the current one.

Where it stops: it needs a background it can resolve. Over an image or a gradient it either declines to report or reports against whatever solid color it found underneath.

Method 2: Lighthouse or axe

A page-wide automated pass catches the obvious failures fast, and you should run one. Just know what it is scoring: the default state of elements whose background resolves to a solid color. That is a real subset of the problem, not the whole of it.

Method 3: an eyedropper on the rendered pixels

This is the method that works everywhere, because it ignores CSS entirely and measures what is actually on screen. Pick the foreground pixel, pick the background pixel behind it, read the ratio.

It is the only approach that gives a real answer for text over a hero image, a gradient, a video, a backdrop-blurred panel or a translucent overlay — which is exactly where contrast problems concentrate, because nobody could check them.

With CSS DNA the eyedropper reports the WCAG ratio with its AA/AAA verdict and the APCA Lc score at the same time, on any pixel of any page. That part is free.

The three failures automated checkers never report

1. Text on images, gradients and video

The scanner cannot resolve a background, so it skips the node. A white headline over a photo passes the audit by not being tested — and fails for a real person the moment the photo is bright at the top.

2. Every state that is not the default

Hover, focus, active, visited and disabled are not rendered during a scan, so they are never graded. In practice hover states fail more often than base states, because they are designed for delight and checked by nobody.

3. Placeholder and helper text

The two places designers reliably reach for the lightest gray in the palette, and both carry real information. Placeholders in particular routinely land around 2.5:1.

Placeholder gray
#5a5f73 on #0f1320 — 2.93:1 · fails AA
Nudged lighter
#9aa0b8 on #0f1320 — 7.14:1 · passes AAA

The fix cost one lightness step. The hue is unchanged, so nothing about the design's character moved.

Check any pixel on any page.Eyedropper with WCAG ratio and APCA Lc — works over images, gradients and states. Free, no account.

Add to Chrome — Free

Method 4: grade the whole palette at once

Checking pairs one at a time finds the failure you already suspected. It does not find the combination nobody has shipped yet but someone will next sprint.

A contrast grid crosses every color in the palette against every other and grades each cell, so you can see the whole space of legal combinations at a glance. Extract a site's full palette, generate the grid, and you get an answer to the useful question — which of our colors may sit on which — rather than a verdict on one pair.

This is also where you find out that the muted text you love works on the page background and fails on cards, which is the single most common real-world contrast bug.

Cross-check with APCA

WCAG 2's ratio is a fixed formula that ignores font size, weight and polarity. It is the legal standard and you should conform to it. It is also known to be wrong in specific, predictable ways — most visibly on dark backgrounds, where it tends to pass light-gray-on-black combinations that are genuinely hard to read.

APCA, the perceptual model drafted for WCAG 3, weights contrast by size, weight and whether text is light-on-dark or dark-on-light. It returns an Lc value rather than a ratio. As a working guide:

  • Lc 75+ — comfortable for body text
  • Lc 60+ — large text
  • Lc 45+ — headlines and display sizes

Use both: WCAG 2 to conform, APCA to catch the cases where conforming still reads badly. Where they disagree, the disagreement itself is the signal. APCA is a draft and is not a conformance requirement today.

Fixing a failure without wrecking the design

Change lightness, not hue. A brand color that shifts hue to pass contrast is no longer the brand color; the same color one step darker usually is.

  1. Hold the hue and chroma, step lightness toward the far end from the background.
  2. Re-measure. Stop at the first step that clears the threshold — overshooting costs you the design intent for no accessibility gain.
  3. If it still fails at a lightness you can live with, the problem is the pairing, not the color. Put the text on a different surface.

CSS DNA's contrast auto-fix runs that loop and returns the nearest passing value, which is faster than nudging hex codes by hand. Working in OKLCH helps here too: lightness is a real axis there, so one step means one step.

Evidence and sources

Thresholds
WCAG 2.2 SC 1.4.3 (Contrast Minimum, AA): 4.5:1 normal text, 3:1 large text. SC 1.4.6 (Contrast Enhanced, AAA): 7:1 and 4.5:1. SC 1.4.11 (Non-text Contrast, AA): 3:1 for UI components and graphical objects. Large text is defined as at least 18pt (24px), or 14pt (18.66px) when bold. Inactive components are explicitly exempt.
APCA
A perceptual contrast model developed for the WCAG 3 working draft, returning a signed Lc value. It is not a WCAG 2 conformance requirement. The Lc 75 / 60 / 45 guidance above reflects common usage bands, not a ratified standard.
Source
W3C WCAG 2.2 — Contrast (Minimum) · W3C — Non-text Contrast · APCA introduction
Verified
August 12, 2026.
Limitations
Automated measurement grades color pairs. It cannot judge whether a passing combination is legible in context — over busy imagery, at small optical sizes, or for a specific user's vision.

A five-minute audit routine

  1. Run Lighthouse for the obvious, resolvable failures.
  2. Eyedropper every piece of text sitting on an image, gradient or overlay.
  3. Force :hover, :focus and :disabled on your primary button and links, and measure each.
  4. Measure placeholder and helper text specifically.
  5. Check borders and focus rings against 3:1, not 4.5:1.
  6. Generate the palette contrast grid once, and keep it — it answers next month's questions too.

Frequently asked questions

What contrast ratio does WCAG require?

WCAG 2.2 Level AA requires 4.5:1 for normal text and 3:1 for large text, meaning 24px and up, or 18.66px and up when bold. Level AAA raises those to 7:1 and 4.5:1. User interface components and graphics need 3:1.

How do I check the contrast of a website I don't own?

Use an eyedropper that reads live rendered pixels. It works on any page, including text over images and gradients, where inspecting CSS values alone tells you nothing about the real background behind the text.

Why does Lighthouse say my contrast passes when it looks wrong?

Automated checkers evaluate the default state against a solid background they can resolve. They skip text over images, gradients and video, and they never test hover, focus or disabled states, because those are not rendered during the scan.

What is a good APCA Lc score?

As a working guide, Lc 75 or above suits body text, Lc 60 or above suits large text, and Lc 45 or above suits headlines. APCA is a WCAG 3 draft model, so it informs design decisions but is not a conformance requirement today.

Do disabled buttons need to pass contrast?

WCAG 2.2 exempts inactive user interface components from the contrast minimum, so a disabled button can technically fail and still conform. Users still have to read it, so treat the exemption as a floor rather than a target.

How do I fix a color that fails contrast?

Adjust lightness rather than hue, so the color keeps its identity. Nudge the foreground darker or lighter in small steps until it clears the threshold. CSS DNA's contrast auto-fix does this and returns the nearest passing value.

Measure contrast on any pixel

WCAG ratio and APCA Lc together, over images, gradients and interaction states — plus a full palette contrast grid.

Add CSS DNA to Chrome — Free

Eyedropper and contrast checks are free · no account · runs on-device