Colour

Color contrast: readable text for everyone

Contrast is the difference between words people read and words people skip. The WCAG numbers in plain English, how to check them, and what changes when the background is a gradient.

GradientlyVerified Gradiently account··5 min read
Cover: Andes Mirror · GR·WVR2·V3

The short version

  • Color contrast is the difference in brightness between text and its background, measured as a ratio from 1:1 (no difference) to 21:1 (black on white).
  • WCAG 2 level AA asks for at least 4.5:1 for normal text and 3:1 for large text, which is about 24 px regular or 18.66 px bold.
  • Icons, input borders and other parts of an interface people need to see also need at least 3:1 against what surrounds them.
  • On white, #767676 is the lightest plain grey that passes 4.5:1 for body text, and #777777 just fails.
  • On a gradient, contrast changes from point to point, so you must test the worst spot behind the words, not the average colour.
On this page

Color contrast is the difference in brightness between text and the colour behind it, and it decides whether people can read your words at all. The Web Content Accessibility Guidelines (WCAG) measure it as a ratio from 1:1, where the two colours are identical, to 21:1, black on white. For level AA, normal text needs at least 4.5:1 and large text at least 3:1. Everything else in this guide is about hitting those numbers without making your design timid.

Contrast matters for everyone, not only for people with low vision. Phones in sunlight, dim projectors, cheap monitors and tired eyes all shrink the difference between colours. Designs with enough contrast simply get read more.

The WCAG contrast ratios in plain words

Three rules in WCAG 2 cover almost every design decision. They come from the W3C's success criteria, and they are what most accessibility audits and regulations refer to.

WhatLevel AALevel AAANotes
Normal text4.5:17:1Body copy, captions, labels, buttons
Large text3:14.5:1At least 18 pt (about 24 px), or 14 pt bold (about 18.66 px)
Icons and interface parts3:13:1Input borders, chart lines that carry meaning, icons without labels
Logos and decorationNoneNoneBrand logotypes and purely decorative text are exempt
Level AA is the usual target. AAA is stricter and worth aiming for in long reading.

Two details catch people out. First, "large" is about the rendered size, so a 24 px heading on a phone that scales it down may stop counting as large. Second, a disabled button is exempt, but a light grey placeholder that people need to understand is not.

How the contrast ratio is calculated

The ratio compares the relative luminance of the two colours: how much light each one gives off, weighted the way the eye sees. Green contributes most, red less and blue very little, which is why a saturated blue can be surprisingly dark and a yellow surprisingly light. The formula is (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter colour.

js
// WCAG 2 contrast ratio between two hex colours
const channel = (c) => {
  c /= 255
  return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
}
const luminance = (hex) => {
  const [r, g, b] = [1, 3, 5].map((i) => channel(parseInt(hex.slice(i, i + 2), 16)))
  return 0.2126 * r + 0.7152 * g + 0.0722 * b
}
const contrast = (a, b) => {
  const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x)
  return (hi + 0.05) / (lo + 0.05)
}

contrast('#767676', '#ffffff') // 4.54, passes for body text
contrast('#777777', '#ffffff') // 4.48, fails
The whole calculation fits in a dozen lines. Useful for checking a brand palette in bulk.

You do not need to calculate it by hand. The WebAIM contrast checker takes two hex codes and tells you which levels pass, and the colour picker in Chrome's developer tools shows the ratio of any text you inspect.

Colour pairs that pass and fail

Brand colours often sit in the awkward middle, too dark for dark text and too light for white text. Medium greens, oranges, pinks and light blues are the usual culprits. These are common pairings, with their real ratios.

Text on backgroundRatioNormal textLarge text
White on #7c3aed violet5.7:1PassPass
White on #8b5cf6 light violet4.2:1FailPass
White on #2563eb blue5.2:1PassPass
White on #3b82f6 sky blue3.7:1FailPass
White on #10b981 green2.5:1FailFail
#0b0b10 near-black on #10b981 green7.7:1PassPass
White on #f59e0b amber2.2:1FailFail
#999999 grey on white2.9:1FailFail
#6b7280 grey on white4.8:1PassPass
A small shift can decide it: two blues that look almost alike land on opposite sides of 4.5:1.

Why gradients make contrast harder

A flat background has one contrast ratio. A gradient has a different one at every point. White text that passes easily over the dark end of a blend can fail completely at the light end, and a headline that stretches across the gradient passes and fails in the same line.

Midnight to violet to pinklinear-gradient(90deg, #1f0b3a 0%, #7c3aed 55%, #f472b6 100%)
White text scores 18:1 at the left, 5.7:1 over the violet and 2.7:1 at the pink end. One gradient, three verdicts.

The rule is simple: test the lightest point behind light text, or the darkest point behind dark text. If the worst point passes, the whole line passes. Average colours and eyedropper samples from the middle will mislead you.

How to fix contrast on a gradient

  1. 1

    Move the words to the calm end

    Place text over the darkest or lightest part of the gradient, and let the bright transition happen away from it.

  2. 2

    Narrow the range behind the text

    Keep the part of the gradient that sits behind words within a small lightness range. The rest of the canvas can be as bold as you like.

  3. 3

    Add a soft scrim

    A gentle dark or light fade behind the text, such as a transparent-to-30% black gradient, lifts contrast without a visible box.

  4. 4

    Go bigger and bolder

    Large text only needs 3:1. A heavier weight and a larger size can turn a failing line into a passing one.

  5. 5

    Test on a real phone

    Check the design at full brightness and at low brightness, outdoors if you can. Ratios are the floor, not the goal.

css
.card {
  background: linear-gradient(90deg, #1f0b3a 0%, #7c3aed 55%, #f472b6 100%);
  color: #ffffff;
}
/* A soft scrim keeps white text above 4.5:1 across the pink end */
.card .text {
  background: linear-gradient(90deg, transparent 0%, rgb(31 11 58 / 0.55) 60%);
  padding: 1rem 1.25rem;
}
The scrim darkens only where the gradient gets light, so the left side stays untouched.

The words run straight over the brightest part of the field and their contrast drops.

The same design with the calm, dark region moved behind the words.

This is the idea behind Gradiently's legibility: a Mark knows where your words are, moves its calmest, best-contrasting region behind them and picks light or dark ink per line from its own palette. For more techniques that work anywhere, read text on a gradient and readable text over photos. For dark interfaces specifically, see designing for dark mode.

Questions people ask

What is a good color contrast ratio?

At least 4.5:1 for normal text and 3:1 for large text meets WCAG level AA. For long reading, 7:1 (level AAA) is more comfortable.

What counts as large text in WCAG?

Text of at least 18 point, about 24 px, or at least 14 point bold, about 18.66 px. Large text only needs 3:1 at level AA.

What is the lightest grey I can use on white?

#767676 is the lightest plain grey that reaches 4.5:1 on white. #777777 measures 4.48:1 and fails for body text.

Do logos need to meet contrast requirements?

No. WCAG exempts text that is part of a logo or brand name, and purely decorative text. Everything people need to read or use still counts.

How do I check contrast on a gradient background?

Measure the text colour against the lightest point behind light text, or the darkest point behind dark text. If that worst point passes, the whole line passes.

Share this guide

Written by GradientlyVerified Gradiently account

The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.

See our profile
All Colour guides