Pale grey text on a white page looks refined on a good monitor. For people with low vision it can be unreadable, and anyone reading a phone in sunlight has the same problem. The good news is that contrast can be measured, so it does not need to be a matter of taste.
The contrast ratio
The Web Content Accessibility Guidelines (WCAG 2.1) define contrast as a ratio between the relative luminance of two colours:
ratio = (L lighter + 0.05) ÷ (L darker + 0.05)
Relative luminance L is a measure of how bright a colour appears. It is calculated from the red, green and blue values after converting them to linear light, weighted 0.2126 for red, 0.7152 for green and 0.0722 for blue. Green dominates because the eye is most sensitive to it. The ratio runs from 1:1 for identical colours to 21:1 for black on white.
What WCAG asks for
| Content | Level AA | Level AAA |
|---|---|---|
| Normal text | 4.5:1 | 7:1 |
| Large text (24px, or 18.66px bold) | 3:1 | 4.5:1 |
| Buttons, icons, input borders | 3:1 | not specified |
Level AA is the usual legal and procurement target.
Two examples
Mid-grey #767676 on white measures 4.54:1. It is the lightest neutral grey that passes AA for normal text. One step lighter, #777777, drops to 4.48:1 and fails.
Toolhouse’s own orange, #e2672d, measures only 3.38:1 against white, so it fails for small text on a light background. Against black it measures 6.21:1. That is why the orange buttons on this site carry dark text, and why the orange used for links and labels in the light theme is a deeper shade.
Common traps
- Placeholder text. Light grey hints inside form fields are text too, and they need 4.5:1.
- Text over images. Contrast changes across the picture. Put a solid or semi-opaque panel behind the text and test against it.
- Colour as the only signal. A red and green status dot is invisible to many people with colour blindness. Add a word or an icon.
- Dark mode. Test it separately. A colour that passes on white may fail on near-black, and inverting a palette does not guarantee anything.
- Hover and focus states. The focus outline is a UI component, and it needs 3:1 against its surroundings.
Fixing a failing colour
Keep the hue, and move the lightness. For text on a light background, make the colour darker until it passes. For text on a dark background, make it lighter. The shade row in the colour converter does this in nine steps from light to dark: click a shade, and the pass or fail labels beneath it update for white and black text.
Try it yourself: Open the colour converter