What this guide covers
- AA: 4.5:1 for normal text, 3:1 for large text.
- AAA: 7:1 for normal text, 4.5:1 for large text.
- UI components and graphics generally need 3:1.
- A brand color can stay in the palette even if it cannot be a text color.
- Fix the pair, not the brand: use darker/lighter steps or different foregrounds.
Live checker
Check any text and background pair
WCAG thresholds: AA 4.5:1 normal and 3:1 large; AAA 7:1 normal and 4.5:1 large.
Normal body copy at 16px. This is the size most people read, and the size most palettes fail.
Small label at 14pxThe thresholds, without the mythology
WCAG 2.2 defines contrast minimums for text and images of text. For AA, normal text needs at least 4.5:1 and large text needs at least 3:1. For AAA, normal text needs 7:1 and large text needs 4.5:1.
Large text is generally at least 18 point (24 CSS pixels) regular weight, or 14 point (about 18.66 CSS pixels) bold. The exact boundary depends on the font and the rendering, so when a design sits near the threshold, use the stricter normal-text rule.
Non-text UI components and graphical objects need at least 3:1 against adjacent colors. That includes input borders, focus indicators, icons that carry meaning, and chart lines. It does not include purely decorative elements.
| Element | AA | AAA |
|---|---|---|
| Normal text | 4.5:1 | 7:1 |
| Large text | 3:1 | 4.5:1 |
| UI components and meaningful graphics | 3:1 | No separate AAA text rule |
| Decorative elements | Not required | Not required |
A brand color can be a background without being a text color
The most common brand-color failure is using the brand color as text on a light background. A bright pink or yellow may be perfect for a logo and unreadable as a 16-pixel link.
The fix is not to abandon the brand color. Keep it as a surface, an accent, a large heading or a decorative element. For text, use a darker step from the same family, or a neutral with enough contrast.
This is why a palette needs more than one version of the brand color. The expressive version and the readable version can share a hue while serving different jobs.
Accessibility does not require a dull brand. It requires the right color for the right job.
Large text is not a loophole
Large text has a lower threshold because bigger glyphs are easier to read at lower contrast. But the threshold applies to the actual rendered size and weight, not to the HTML element. An `<h2>` at 16 pixels is not large text.
Thin font weights can make a pair feel lower-contrast than the number suggests. A 3:1 heading in a light weight may be harder to read than a 3:1 heading in a bold weight. Consider the visual weight in the final review.
Do not use large text to justify low-contrast body copy. The rule is about size, not about moving content into a heading so it can be dimmer.
How to fix a failing pair
First, try the opposite foreground. If the current text is dark, try white; if it is white, try black. Many failures are solved by choosing the right foreground for the background.
If neither works, adjust the background. Darkening a light background or lightening a dark background usually increases the ratio. Keep the hue if you want to preserve the brand feel.
If the background must stay, choose a darker or lighter step of the brand color for the text. The original color can remain as a surface or a graphic.
Check the final pair in the actual component. A button may have a border, a shadow or a hover state that changes the effective background. Measure the worst case.
- Try black text.
- Try white text.
- Adjust the background lightness.
- Use a darker or lighter brand step for text.
- Measure the worst state, including hover and disabled.
Contrast is necessary, not sufficient
A page can pass every contrast check and still be inaccessible. Keyboard users need visible focus. Screen-reader users need labels and semantics. Motion-sensitive users need reduced motion. Touch users need targets large enough to hit.
Color should not be the only way to communicate state. An error should have an icon or a text label, not just red text. A chart line should have a pattern or a label, not just a different hue.
Use contrast as one gate in a broader review. It catches a common, objective failure early, which is valuable. It does not replace testing with real users and assistive technology.
A useful habit is to review the interface with the color removed. Convert a screenshot to grayscale and look at the hierarchy. If two states that should be different become identical, the design is relying too heavily on hue and needs a second cue.
A practical contrast workflow
List the pairs the product actually uses: body text, muted text, button text, link text, placeholder, border, focus ring and status text. Measure each one against its real background.
Record the ratio next to the token pair. When a token changes, re-measure the pairs that depend on it. A small change to a background can break several text pairs at once.
Run the check in both light and dark mode. The same token may pass in one mode and fail in the other. Treat the dark theme as a separate set of pairs.
