Methodology

Color contrast explained: WCAG ratios, thresholds and limits

A contrast ratio compares two colors. It can tell you whether that pair meets a text contrast threshold. It cannot certify a palette, a component, or an entire website.

Reviewed 7 October 2026 · 3 min read

The thresholds at a glance

WCAG 2.2 text contrast criteria
LevelNormal textLarge text
AA (1.4.3)4.5:13:1
AAA (1.4.6)7:14.5:1

Large text is at least 18 points regular or 14 points bold, equivalent to 24 CSS pixels or approximately 18.67 CSS pixels. A label that simply looks big is not necessarily large text under this definition. The AA criterion and AAA criterion include exceptions, such as certain incidental text and logotypes.

Our “AA text” and “AAA text” labels mean normal text reaches the indicated contrast threshold. “Large text only” means the pair reaches 3:1 but falls short of 4.5:1. It does not mean every use of those colors is accessible.

How the calculation works

We accept opaque three- or six-digit sRGB hex colors. Three digits expand into six: #ABC becomes #AABBCC. Each red, green, and blue channel is divided by 255 to give a value between 0 and 1.

Each channel is then linearized: if its value is at most 0.04045, divide it by 12.92. Otherwise calculate ((channel + 0.055) / 1.055) ^ 2.4. Relative luminance is the weighted sum:

L = 0.2126 × R + 0.7152 × G + 0.0722 × B
Contrast = (lighter L + 0.05) / (darker L + 0.05)

The result ranges from 1:1 for identical luminance to 21:1 for black against white. This follows the W3C definitions of relative luminance and contrast ratio. Reversing foreground and background gives the same numeric ratio.

Why we do not round a pass

Pass/fail uses the full calculated value. A ratio of 4.499:1 fails a 4.5:1 threshold even though rounding to two decimals would display 4.50. The studio normally displays two decimal places, and displays four near the 3, 4.5, and 7 boundaries. The displayed precision is a convenience; classification always uses the unrounded number.

For a concrete borderline example, white on #777777 is approximately 4.48:1 and fails AA normal text. Black on that same gray is approximately 4.69:1 and passes. That is why our derived button-label color compares true black and white.

Text contrast is not component contrast

Essential visual information identifying a control or its state generally needs 3:1 against adjacent colors. Meaningful graphical objects can fall under the same criterion. This does not require every decorative line or every pair of hover/default colors to contrast at 3:1. The actual function and surroundings matter. Read the W3C non-text contrast guidance.

The studio component report explicitly checks meaningful button boundaries, input borders and offset focus rings at 3:1 against page and surface. Its separate full matrix labels text thresholds for exploration. The meaning of a boundary still depends on the actual component and surroundings; decorative lines need not all meet the UI threshold.

What this tool does not check

Use contrast as a minimum constraint and inspect the result. More contrast can help, but no single number captures the whole reading experience. Pair labels with color where meaning matters; W3C’s use-of-color guidance explains why.

Check a palette in context

The studio shows intended pairs and a matrix of every role combination.

Open the contrast studio ↗

Our examples use original palette values and the WCAG 2.2 calculation. Full methodology and primary sources.

← All field notes