Accessible Color Contrast: A Practical WCAG Guide
Good contrast is not a design preference. It is the difference between text people can read and text they skip, squint at, or abandon. This guide explains the WCAG contrast rules in plain language — and how to fix a palette that fails them.
Why contrast matters more than you think
About one in twelve men and one in two hundred women has some form of color vision deficiency, and far more people read in bad light, on small screens, on aging eyes, or with a cracked phone display. Low-contrast text punishes all of them. Light gray body text on a white background is the most common offender: it looks clean and modern in a design mockup on a bright monitor, and it is genuinely hard to read on a phone in sunlight. The cost is not abstract. If visitors cannot read your prices, your form labels, or your call to action, they leave — and they do not tell you why.
The Web Content Accessibility Guidelines (WCAG) exist to make this measurable instead of a matter of taste. They define contrast as a ratio between 1:1 and 21:1, and they set minimum ratios for text and interface elements. Meeting those minimums is also a legal matter in many contexts: the Americans with Disabilities Act has been applied to websites in the United States, and WCAG 2.1 AA is the standard courts and regulators most often point to. Designing for contrast is therefore both good design and risk management.
How the ratio is calculated
The contrast ratio comes from a quantity called relative luminance — how bright a color appears to the human eye, on a scale from 0 (black) to 1 (white). Luminance is not the average of the red, green, and blue channels, because human vision is not equally sensitive to all three. Green contributes the most, red is next, and blue contributes the least. The weights in the WCAG formula reflect that: 0.2126 for red, 0.7152 for green, and 0.0722 for blue. That is why a pure blue can look darker than a pure green of the same nominal brightness, and why blue text on a white background often fails while green text of the same lightness passes.
Before the weights are applied, each channel is converted from the screen’s gamma-encoded value to linear light. A channel value of 128 out of 255 is not half as bright as 255; because of gamma, it is only about 22 percent as bright in linear terms. The formula handles this with a curve: values at or below 0.03928 are divided by 12.92, and larger values go through a power of 2.4. Once both colors have a luminance, the ratio is the lighter luminance plus 0.05, divided by the darker luminance plus 0.05. The 0.05 terms keep the ratio finite when one color is pure black. Black on white gives (1 + 0.05) / (0 + 0.05) = 21:1, the maximum possible score. Two identical colors give 1:1.
The thresholds: AA and AAA
WCAG defines two conformance levels that matter for contrast. AA is the level most organizations target. For normal text — anything smaller than 18pt, or smaller than 14pt bold — AA requires a ratio of at least 4.5:1. For large text (18pt and up, or 14pt bold and up), AA requires only 3:1, because larger letters are easier to distinguish. AAA is stricter: 7:1 for normal text and 4.5:1 for large text. AAA is worth aiming for on sites where reading is the core task, such as government, healthcare, and education, but AA is the widely accepted standard, and a site that meets AA everywhere is doing well.
Contrast rules do not stop at text. WCAG 2.1 also requires a 3:1 ratio for user-interface components and meaningful graphics against adjacent colors — the border of a text field, the outline of a button, the lines of a chart. A form field with a barely visible border fails even if its label text passes.
Why gray text fails so often
Gray is the color that fails most, because it sits close to white in luminance. A medium gray like #9CA3AF on white scores about 2.5:1 — well below the 4.5:1 needed for body text, and below even the 3:1 needed for large text. A darker gray like #6B7280 scores about 4.8:1, which just passes AA for normal text. And #4B5563 scores about 7:1, clearing AAA. The difference between a failing gray and a passing one is smaller than most designers expect, which is why guessing is a bad strategy: check the number, and adjust the lightness until it passes with margin.
How to fix a failing palette
When a combination fails, the fix is usually a lightness change, not a hue change. Darken the text or lighten the background until the ratio clears the threshold. Working in HSL makes this easy: keep the hue and saturation, and move the lightness. A blue like #2563EB on white scores 5.17:1 and passes AA for body text; if you need AAA, darken it to #1D4ED8 and check again rather than picking a different blue at random. If the brand color cannot change, change where it is used instead: a light brand color that fails for body text may pass for large headings, for a background behind dark text, or for a decorative element that carries no information.
Check contrast in context, not just in a tool. A ratio is calculated for flat colors, but real text sits on images, gradients, and translucent overlays, where the background luminance varies across the text. Put a solid or semi-opaque backing behind text on images, or darken the image, and test the worst case — the lightest part of the background behind the lightest part of the text. Also test in dark mode if your site has one: a palette that passes on a white background often fails when the same text color is placed on a dark background, because the ratio is symmetric only in the sense that swapping foreground and background gives the same number — a light text color that passed on white will score very differently on near-black.
Finally, make contrast part of the design system, not a one-time audit. Define your text colors as pairs — a foreground and a background that are known to pass — and forbid new combinations that have not been checked. Add a contrast check to your design review, the same way you check spelling. The tools are free and the check takes seconds; the alternative is a site that a meaningful share of your visitors cannot read, which is a strange thing to ship on purpose.
Check your own palette now with the Color Converter & Contrast Checker: enter your text and background colors and see the ratio and the WCAG verdict in one click.