Color Contrast and WCAG: What the Numbers Mean
By Sarah Mitchell ยท Published 2026-07-15 ยท 8 min read
WCAG contrast requirements are quoted as ratios: 4.5:1 for normal text, 3:1 for large text and interface components, 7:1 for the strictest level. Designers memorize the numbers, but the numbers mean something specific, and understanding the math behind them makes it far easier to pick colors that pass without trial and error.
A contrast ratio is not a visual judgment. It is a division problem performed on two numbers called relative luminance values, one for the text color and one for the background. Once you can compute luminance, you can predict the WCAG outcome of any color pair before running it through a checker.
The Ratio Formula
The WCAG 2.x contrast ratio is (L1 + 0.05) / (L2 + 0.05), where L1 is the luminance of the lighter color and L2 the luminance of the darker color. The 0.05 term is a small floor added to both sides, modeling the fact that no display is perfectly black and that real screens reflect some ambient light. The ratio for black text on a white background is therefore (1.0 + 0.05) / (0.0 + 0.05) = 21:1, the theoretical maximum. Every other pair on a typical monitor sits somewhere between 1:1 and that ceiling.
Because the ratio is a quotient, small changes in a light color matter more than small changes in a dark one. Dropping a mid-gray background from 50 percent to 45 percent brightness moves the ratio substantially, while darkening an already-dark navy barely moves it at all.
Relative Luminance: Where the Heavy Lifting Happens
Luminance is a single number between 0 and 1 that describes how bright a color appears. It is not an average of the RGB channels, because the human eye is far more sensitive to green than to red or blue. The WCAG formula applies the weights 0.2126 to red, 0.7152 to green, and 0.0722 to blue.
The other wrinkle is that screen brightness is not linear. A channel value of 128 out of 255 is not half as bright as 255; it is much dimmer, because displays apply a gamma curve. The formula converts each channel with a power function before weighting it. A hex value of #ffffff gives luminance 1.0, #000000 gives 0.0, and everything else lands in between.
Worked Example: Reading a Pass and a Fail
Take the dark navy #002244 on white. The red channel is 0, so it contributes nothing. Green is 0x22, which is 34 out of 255, and after the gamma conversion it linearizes to about 0.016. Blue is 0x44, or 68 out of 255, linearizing to about 0.058. Weighted and summed, luminance comes to roughly 0.016. The ratio against white is (1.0 + 0.05) / (0.016 + 0.05) โ 16:1. That pair clears even the AAA threshold of 7:1, with a wide margin, which is why deep navy on white is such a safe choice for body text.
Now try light gray #b8b8b8 on white. All three channels are 184 out of 255, and after gamma conversion each linearizes to about 0.479. Weighted, the luminance is still 0.479, because a gray uses all three channels equally. The ratio is (1.05) / (0.479 + 0.05) โ 1.98:1. That pair fails every WCAG threshold, including the 3:1 requirement for large text and interface components. The two examples bracket the range of practical choices: one is a slam-dunk pass, the other a total failure, and the formula explains both.
The Four Thresholds and What They Apply To
The commonly quoted numbers map to specific requirements. AA level requires 4.5:1 for normal text and 3:1 for large text. AAA level raises that to 7:1 for normal text and 4.5:1 for large text. "Large" is defined as 18 point (about 24 pixels) regular weight, or 14 point (about 19 pixels) bold. The same 3:1 figure also applies to the visual states of UI components: borders of form fields, focus indicators, and the boundaries of buttons that must be perceivable against their surroundings.
Text is treated more strictly than UI because reading small, dense letterforms places the highest demand on contrast. A focus ring at 3:1 is acceptable, while body copy at 3:1 would be a strain for many readers, especially in low light or on low-quality displays.
Why a Pass Is Not a Promise
The WCAG formula assumes a standard monitor in typical conditions. Real-world rendering adds variables the ratio does not capture. Font weight and size change how contrast is perceived, anti-aliasing blends text edges into the background, and subpixel rendering behaves differently on low-DPI screens. Text placed over a photo or gradient has a contrast ratio that shifts from pixel to pixel, so a checker that samples a single point can overstate the result.
The practical response is to build in headroom. If AA requires 4.5:1, target 5.5:1 or better for body text. If you need AAA at 7:1, aim for 8:1 or more. The margin absorbs the differences between your design tool, your users' screens, and the assumptions baked into the formula. For text over images, check the pair at the lowest-contrast point in the image, or add a scrim behind the text.
Checking Your Own Color Pairs
The color contrast checker on this site runs the WCAG calculation for any two colors you enter, reports the ratio, and lists which AA and AAA thresholds the pair satisfies. Because it runs in your browser, you can tune foreground and background quickly and see the number move as you approach a threshold. Use it to check the pairs you are considering, not just the ones you already chose.
Related tools
- Color converter - translate between HEX, RGB, and HSL
- Image color picker - sample colors from an image
- Color palette generator - build harmonious palettes