WCAG Color Contrast Explained: Ratios, AA vs AAA and How to Check
What a contrast ratio is, the WCAG thresholds of 4.5:1 and 3:1, how AA differs from AAA, the exceptions, and how to check and fix failing text and UI colors.
Updated
WCAG color contrast is a ratio between the lightness of a foreground color and its background, from 1:1 (identical) to 21:1 (black on white). Level AA requires at least 4.5:1 for normal text and 3:1 for large text and UI components. Level AAA raises the text thresholds to 7:1 and 4.5:1. The rest of this guide explains where those numbers come from, what counts as large text, and how to fix a failing pair.
How the ratio is calculated
The ratio compares the relative luminance of two colors. Relative luminance is a measure of how bright a color appears, weighted to match the eye: green counts for about 71 percent, red for 21 percent and blue for 7 percent. Each sRGB channel is first linearised, because screen values are gamma-encoded and 128 is nowhere near half as bright as 255.
With the luminance of the lighter color as L1 and the darker as L2, the contrast ratio is (L1 + 0.05) / (L2 + 0.05). The 0.05 represents ambient light reflecting off the screen and stops the ratio reaching infinity on black.
Some reference points on a white background:
- Black
#000000gives21:1. #595959gives exactly7:1, the AAA threshold.#767676gives4.54:1, the lightest grey that passes AA.#777777gives4.48:1and fails. One step makes the difference.- Pure red
#ff0000gives4:1, which fails for normal text. - Orange
#ff6600gives2.94:1, which fails even for large text.
The order of the colors does not matter. White text on #767676 has the same ratio as #767676 text on white, so dark mode is checked the same way.
The thresholds: AA versus AAA
WCAG has three conformance levels. Level A has no contrast requirement for color. Level AA is the standard referenced by most accessibility law and procurement rules, including Section 508 in the US, EN 301 549 in Europe and the ADA guidance that cites WCAG 2.1 AA. Level AAA is stricter and rarely required across a whole site.
For text, success criterion 1.4.3 (AA) requires:
4.5:1for normal text.3:1for large text.
Success criterion 1.4.6 (AAA) requires:
7:1for normal text.4.5:1for large text.
Large text means at least 18 point, which is 24px, in a regular weight, or at least 14 point bold, which is about 18.66px. Most body text at 16px is normal text and needs the full 4.5:1.
WCAG 2.1 added success criterion 1.4.11 for non-text contrast. Under AA, the visible boundary of a form field, the shape of a checkbox, a focus ring and an icon that carries meaning all need at least 3:1 against adjacent colors. A pale grey input border on white is the most common failure here.
What is exempt
A few things are excluded from the text rules:
- Logos and brand names.
- Purely decorative text that conveys nothing, such as a word in a background texture.
- Text in an image that is part of a photograph or is otherwise incidental.
- Disabled or inactive controls.
Placeholder text is a trap. Browsers render it light by default, and it is not exempt when it carries the only hint about what to type. Either darken it to 4.5:1 or move the hint into a visible label.
Contrast is measured against the actual background behind the text. Text over a photo, a gradient or a translucent panel must pass at its worst spot. If the background varies, add a solid or semi-opaque backing layer and measure against that.
Checking a color pair
You do not need to do the luminance math by hand. Paste the foreground and background into the Contrast Checker to get the exact ratio with a live text preview and pass or fail badges for AA and AAA at both normal and large sizes. It uses the standard WCAG formula, so the result matches what an auditor will report.
If your colors are in RGB or HSL rather than hex, the Color Converter turns them into the hex form a checker expects, and back again once you have adjusted them.
Fixing a failing pair
The quickest fix is usually to move lightness, not hue. Brand colors live in the mid range where contrast is weakest. Take Tailwind blue #3b82f6: on white it reaches only 3.68:1, so it works for large headings and buttons but not body text or links. The darker shade #1d4ed8 gives 6.7:1 and passes AA comfortably. Keep the vivid blue for large elements and backgrounds, and use the dark shade where text is small.
Other reliable moves:
- Use a near-black such as
#1a1a1ainstead of pure black for body text, which still gives over17:1on white. - For text on a colored button, test both white and near-black. Yellow
#facc15gives1.53:1with white text and13.71:1with black. - Make text larger or bolder so the
3:1large-text threshold applies, if the design allows. - Underline links so color is not the only indicator, which addresses a separate criterion, 1.4.1.
When you need a whole set of shades that stay on brand, the Color Palette Generator produces a tint and shade scale from one hex value, so you can pick the step that clears 4.5:1 instead of guessing.
Other tools for this work live in the colors category.
Try it
Open the Contrast Checker, enter #3b82f6 on #ffffff, and watch it fail normal text at 3.68:1. Change the foreground to #1d4ed8 and see every AA badge turn green.