Know which threshold applies
WCAG 2.2 AA requires at least 4.5:1 for normal text and 3:1 for large text. AAA raises those text thresholds to 7:1 and 4.5:1. Large text means at least 18 point (roughly 24 CSS pixels) in regular weight, or 14 point (roughly 18.66 CSS pixels) in bold. Do not label a visually prominent 16-pixel heading “large” just because it feels important.
Meaningful non-text parts of controls and graphical objects generally need 3:1 against adjacent colors. Think of an input border needed to find the field, a focus ring, a selected tab indicator, or a line in a chart. Decorative shapes and disabled controls have exceptions, but using an exception should be an intentional decision, not a shortcut.
- 4.5:1 — normal text, AA
- 3:1 — large text, AA
- 7:1 — normal text, AAA
- 4.5:1 — large text, AAA
- 3:1 — meaningful UI and graphical boundaries
Understand what the ratio measures
The formula derives relative luminance from linearized sRGB channels. The lighter luminance plus 0.05 is divided by the darker luminance plus 0.05. Equal colors produce 1:1; ideal white and black produce 21:1. It is a luminance comparison, not a measure of hue difference or subjective beauty.
Thresholds are strict. A computed 4.49:1 does not meet 4.5:1 and should not be rounded up into a pass. Tools may display slightly different last decimals because values are rounded for presentation, but a borderline token is fragile anyway. Give important text a little margin for blending, antialiasing, and future theme changes.
#777777 on white is about 4.478:1, so it misses normal-text AA even though many informal examples round it to 4.5.
Test the complete state matrix
A default component can pass while its hover or selected state fails. Make a small matrix of foreground, background, border, icon, and focus colors for default, hover, pressed, focus, selected, error, success, and disabled. Check both light and dark themes if they exist.
Avoid lowering opacity to create every secondary state. Opacity blends with whatever sits underneath, so the resulting color and ratio change by surface. Calculate the final composited color or use an explicit opaque token for critical text. A disabled control may be exempt, but nearby instructions and error explanations are not disabled simply because they are visually quiet.
Treat images, gradients, and overlays as many backgrounds
One sampled color cannot represent a photograph or gradient. Test the worst light and dark points behind the actual glyphs at each responsive size. Cropping can move a bright cloud from beside a headline to directly underneath it on mobile.
Reliable patterns include placing text in a known solid region, adding a sufficiently strong scrim, using a solid text container, or changing the composition by breakpoint. Text shadow alone usually does not create a stable measurable surface. If the content image changes dynamically, build a safety layer instead of manually approving one sample.
Do not confuse contrast with use of color
A red error border with excellent contrast can still fail users if red is the only indication of error. Add an icon, explanatory text, and programmatic error association. Likewise, two chart lines can each contrast with the white background but remain indistinguishable from one another.
Use labels, shapes, line styles, patterns, and position to preserve meaning. Contrast answers “can this edge or text be perceived against its neighbor?” Use of color answers “does understanding require identifying the hue?” Both questions belong in the same design review.
Build contrast into tokens and review
Store approved foreground-on-background pairings, not just isolated color swatches. A semantic token such as text-on-primary should point to a tested value and be exercised in automated component checks. Prevent arbitrary text colors from being placed on arbitrary surfaces.
Automated math is fast and deterministic, but finish with zoom, keyboard focus, forced-colors or high-contrast settings, different displays, and human review. A ratio cannot tell you whether the font is too thin, the focus order is confusing, or a status label lacks meaning.
Contrast review checklist
- The correct text-size threshold was used.
- Borderline ratios were not rounded into a pass.
- All interactive and semantic states were checked.
- Focus indicators contrast with both adjacent areas.
- Transparent colors were measured after compositing.
- Text over images and gradients was checked at each crop.
- Errors and chart series do not rely on hue alone.
- Automated results were followed by real component review.
Frequently asked questions
Is 4.5:1 always required for text?
It is the WCAG AA threshold for normal text. Large text can use 3:1, while logos, incidental text, and inactive controls have specific exceptions. Confirm the exact criterion instead of assuming.
Can I round 4.48:1 to 4.5:1?
No. W3C guidance says computed values should not be rounded up to meet a threshold. Adjust one of the colors until the unrounded ratio passes.
Do disabled buttons need 3:1 contrast?
Inactive UI components have an exception under the minimum contrast criterion. Still make the state understandable, and do not apply the exception to essential instructions or information.