Color contrast decides whether people can actually read your text. Low contrast looks stylish in a design mockup on a bright monitor, then disappears in sunlight, on a cheap panel, or for anyone with reduced vision. The Web Content Accessibility Guidelines (WCAG) turn “readable” into a number you can test, and that number is the contrast ratio. This guide explains what the ratio means, where the thresholds come from, and how to fix a failing pair fast.
What the contrast ratio means
Contrast ratio is a single number comparing the lightness of two colors, usually text against its background. It ranges from 1:1 to 21:1.
A ratio of 1:1 means the two colors are identical: invisible text. The maximum, 21:1, is pure black (#000000) on pure white (#ffffff). Everything real sits between those bounds. Mid-gray text on white might land around 4:1; light gray on white can drop below 2:1 and become nearly unreadable.
The formula is (L1 + 0.05) / (L2 + 0.05), where L1 is the relative luminance of the lighter color and L2 the luminance of the darker one. The 0.05 terms model ambient light reflecting off a screen, which stops the ratio from exploding toward infinity near pure black.
The WCAG thresholds
WCAG defines two conformance levels that matter for contrast.
Level AA, the common legal and practical target, requires:
- 4.5:1 for normal body text
- 3:1 for large text
- 3:1 for user interface components and meaningful graphics, such as input borders, icons, and focus indicators
Level AAA is stricter:
- 7:1 for normal text
- 4.5:1 for large text
“Large text” has a specific definition: at least 18.66px (14pt) bold, or 24px (18pt) regular. Anything smaller counts as normal text and must clear the higher bar.
Why large and bold text gets a lower bar
Larger and heavier letterforms present more colored area per character and thicker strokes, so the eye separates them from the background more easily even when the measured ratio is lower. A thin 12px gray label and a bold 24px heading in the same gray do not read the same; the heading stays legible while the label smears. WCAG encodes that reality by letting large text pass at 3:1 (AA) instead of 4.5:1. The tradeoff is deliberate: it lets designers use lighter accent colors for headings without hurting readability.
How relative luminance is computed
The ratio depends on relative luminance, which is not the same as the raw RGB values. Screen colors are stored in the sRGB color space, which is gamma-encoded, so you cannot average the channels directly. The computation has two steps.
First, linearize each channel. Take each 8-bit value and divide by 255 to get a number from 0 to 1. Then, for each channel value c: if c is at most 0.03928, use c / 12.92; otherwise use ((c + 0.055) / 1.055) raised to the 2.4 power. This reverses the sRGB gamma curve and gives light-linear values.
Second, weight and sum the linear channels:
L = 0.2126 * R + 0.7152 * G + 0.0722 * B
The weights reflect how the human eye perceives brightness: green contributes most, red less, and blue least. That is why swapping a blue for a green of the “same” brightness can shift a passing pair to failing, or the reverse. Once you have L for both colors, plug the larger and smaller into (L1 + 0.05) / (L2 + 0.05).
Checking and fixing contrast
You do not need to run the math by hand. Paste two colors into the color contrast checker and it reports the exact ratio plus pass or fail badges for AA and AAA at both text sizes. Adjust one color and the number updates so you can dial in the smallest change that passes.
When a pair fails, try these fixes in order:
- Darken the text or lighten the background. Small nudges move the ratio more than you expect near the middle of the range.
- Keep the hue, change the lightness. If the brand insists on a specific color, hold its hue and shift only its lightness until the ratio clears. A color picker lets you read and edit HSL values while watching the ratio.
- Add a solid backing. Text over a photo or a CSS gradient can pass in one spot and fail in another. A semi-opaque panel or a text shadow gives a consistent background luminance.
- Increase size or weight. Bumping a label to large-text dimensions drops its requirement from 4.5:1 to 3:1, which sometimes rescues a borderline color without changing it at all.
The bottom line
Contrast is one measurable number between 1:1 and 21:1, driven by relative luminance and the green-heavy weighting of human vision. Aim for 4.5:1 on body text, 3:1 on large text and UI parts, and 7:1 when you want AAA. Test every text-on-color pair before shipping, and fix failures by moving lightness rather than guessing at hue.