Answer 23 of 50
How to Achieve and Test Contrast Ratio Standards in Web Design
To meet WCAG 2.2 Level AA, normal text needs a contrast ratio of at least 4.5:1 against its background, large text at least 3:1, and the visual parts of controls and meaningful graphics at least 3:1. The ratio is calculated, not judged by eye, and it is not rounded, so a gray that measures 4.48:1 fails even though it looks identical to one that measures 4.54:1. Achieving the standard is mostly a matter of choosing approved color pairs early and testing the places tools miss.
The thresholds
| What | Level AA | Level AAA |
|---|---|---|
| Normal text | 4.5:1 | 7:1 |
| Large text: at least 18pt, or 14pt bold | 3:1 | 4.5:1 |
| User interface components and graphical objects needed to understand the content | 3:1 | No separate AAA level |
The text figures come from Understanding 1.4.3 Contrast (Minimum) and 1.4.6 Contrast (Enhanced); the component and graphics figure from 1.4.11 Non-text Contrast.
Two details turn these into numbers a front-end team can use. First, WCAG measures type in points; the Understanding page states “1pt = 1.333px, therefore 14pt and 18pt are equivalent to approximately 18.5px and 24px.” So a 20px bold heading counts as large text, while a 20px regular heading does not. Second, the same page says “the computed values should not be rounded (e.g., 4.499:1 would not meet the 4.5:1 threshold).”
How the ratio is calculated
The ratio is (L1 + 0.05) / (L2 + 0.05), where L1 is the relative luminance of the lighter color and L2 of the darker. Relative luminance weights the red, green, and blue channels (0.2126, 0.7152, 0.0722) after converting each from its sRGB value to linear light. The scale runs from 1:1, the same color twice, to 21:1, black on white.
A worked example with gray text on white, calculated with the WCAG 2.2 formula:
| Text color on white | Contrast ratio | Normal text at AA |
|---|---|---|
| #767676 | 4.54:1 | Passes |
| #777777 | 4.48:1 | Fails |
| #949494 | 3.03:1 | Large text and components only |
| #0066CC | 5.57:1 | Passes |
One step on the hex scale moves #777777 below the line, which is why approved pairs should be written down with their measured ratios rather than described as “dark gray.”
What the standard exempts
1.4.3 lists three kinds of text with no contrast requirement:
- Incidental text: text that is part of an inactive user interface component, pure decoration, not visible to anyone, or part of a picture that contains significant other visual content.
- Logotypes: “Text that is part of a logo or brand name has no contrast requirement.”
- Inactive controls: the Understanding page spells out that “User Interface Components that are not available for user interaction (e.g., a disabled control in HTML) are not required to meet contrast requirements.”
The last point is easy to misreport as a failure. A grayed-out disabled button does not break 1.4.3 or 1.4.11. It can still confuse people, so if an option is unavailable, explain why in readable text nearby.
Placeholder text is not exempt; the 1.4.3 Understanding page includes it among the text the criterion applies to, so a light gray hint inside a form field has to meet 4.5:1 like any other text.
Controls, focus, and states
1.4.11 applies to the visual information needed to identify a control and its state, and its Understanding page draws three useful lines:
- Borders are needed only sometimes. A text field’s border needs 3:1 against adjacent colors when it is the only visual cue that the field exists; the criterion “does not require that controls have a visual boundary” when visible text or a contrasting icon already identifies the control.
- Focus indicators need contrast. Combined with 2.4.7 Focus Visible, the visible focus indicator must have sufficient contrast against the adjacent background when the component is focused.
- Hover styling is extra. Author-supplied hover treatments are not required to identify the hover state, but they should not lower the contrast of the component or its other indicators.
Testing during design and in production
| Stage | Tool | What it does well | Where it falls short |
|---|---|---|---|
| Design | Design tool contrast plugins | Flags failing pairs as you work | Only checks the pairs you select |
| Quick check | WebAIM Contrast Checker | Enter two colors, see AA and AAA results for text and graphics | One pair at a time |
| In the browser | Chrome DevTools color picker | Shows the ratio and whether it meets AA or AAA for inspected text | Single color backgrounds |
| Whole page | Automated scanners such as axe or Lighthouse | Finds failing text across a page and catches regressions in CI | Text over images, gradients, and transparency |
| Hard cases | A pixel sampler | Compares text against the actual pixels behind it | Manual |
The tools: WebAIM’s contrast checker, and Chrome’s documentation for checking contrast in DevTools, which says the color picker tells you when a ratio does not meet the AA or AAA level. web.dev’s article on testing web design color contrast explains why gradients and transparency need a pixel-level tool, and recommends comparing the text against a range of background sample pixels, including the lightest.
Text over images and gradients
For text over a photo or gradient, measure against the lightest pixel behind the text for dark-on-light designs, and the darkest for light-on-dark. If any part fails, change the design rather than the measurement:
- Put a solid or semi-transparent overlay behind the text and measure the result.
- Place the text in a solid panel over the image.
- Choose or crop a different image so the text sits on a calm, uniform area.
- Move the text off the image entirely.
Brand colors that fall short
A brand blue that fails on white for body text can stay in the logo and in decoration, since logotypes are exempt and decoration has no requirement. For text and controls, add a darker or lighter variant to the palette, or change the background it sits on. Then publish an approved-pairs table in the design system with hex values and measured ratios, like the worked example above, so designers pick from pairs that pass instead of checking every new combination.
Dark themes need their own pass. The thresholds are the same, but a color that works on white may not on near-black, so measure every functional pair in both themes. Color vision and low vision considerations beyond contrast are covered in designing for color blindness and visual impairments.
About newer contrast methods
WCAG 3.0 is still a W3C Working Draft. Until it becomes a Recommendation and a law or contract references it, the 2.x ratios above are the ones audits and legal requirements measure against; why that matters legally is covered in why web accessibility has become a legal requirement.
Pick colors from an approved-pairs table with measured ratios, never round a ratio up, exempt disabled controls correctly, and test text over images by hand.