Colour contrast ratios and WCAG: a plain guide
Pale grey text on a white background looks stylish on a designer's screen, and it is hard to read on a phone in sunlight, for someone over fifty, or for anyone with low vision. Colour contrast is one of the most common accessibility problems on the web, and one of the easiest to fix once you know how it is measured. This guide explains the contrast ratio, the thresholds set out in the Web Content Accessibility Guidelines, a worked calculation for a real pair of colours, a table of examples that pass and fail, and practical ways to fix a failing design without ruining its look. It also covers what contrast does not cover, such as colour blindness and text size.
Why contrast matters
Contrast is the difference in brightness between text and its background. When it is too low, letters blur into the page. The effect is worse for people with low vision, colour vision deficiency or age-related changes to the eyes, and for anyone in bright light, on a dim screen, or tired.
In the UK, public sector websites must meet accessibility requirements based on the Web Content Accessibility Guidelines, WCAG, at level AA. Organisations outside the public sector are covered by the Equality Act 2010, which requires reasonable adjustments, and WCAG AA is widely used as the benchmark. Even where the law does not demand it, readable text is good for every visitor.
The guidelines give a precise test for contrast, which means you can measure it instead of arguing about taste.
How the contrast ratio is calculated
WCAG compares the relative luminance of two colours, which is a measure of how bright each appears. The ratio is (L1 plus 0.05) divided by (L2 plus 0.05), where L1 is the lighter colour's luminance and L2 is the darker. The result runs from 1 to 1, no contrast at all, up to 21 to 1, which is black on white.
Luminance itself is calculated from the red, green and blue values. Each channel is converted from a 0 to 255 number to a 0 to 1 number, adjusted for the way screens display brightness, and combined with weights of 0.2126 for red, 0.7152 for green and 0.0722 for blue. Green counts for most because the eye is most sensitive to it.
You do not need to do this by hand. A contrast checker takes two colours and reports the ratio. But a worked example shows what is going on.
A worked example: mid grey on white
Take grey text with the colour code #767676 on a white background. Each channel of #767676 is 118 out of 255, which is 0.4627. After adjusting for screen brightness, that becomes 0.1812. As all three channels are equal, the luminance of the grey is 0.1812. White has a luminance of 1.
The ratio is (1 plus 0.05) divided by (0.1812 plus 0.05), which is 1.05 divided by 0.2312, giving 4.54 to 1. That passes the 4.5 to 1 requirement for normal text, just.
Now try #777777, which looks almost identical. Its luminance is 0.1845, and the ratio is 1.05 divided by 0.2345, which is 4.48 to 1. That fails. This is the well-known example of how close the line is, and why you should measure instead of judging by eye.
The thresholds
For level AA, the minimum contrast ratio is 4.5 to 1 for normal text, and 3 to 1 for large text. Large text is at least 18 point, which is 24 pixels, or at least 14 point bold, about 18.7 pixels. For level AAA, the stricter level, the targets are 7 to 1 for normal text and 4.5 to 1 for large text.
In WCAG 2.1 and later there is also a requirement of at least 3 to 1 for user interface components and graphics that carry meaning: the border of a text field, the outline of a checkbox, the parts of a chart or an icon with no text label. A pale grey outline on a white form field often fails this.
Exceptions exist for purely decorative elements, for text that is part of a logo, and for inactive controls, such as a greyed-out button. Even so, it is kind to keep a disabled button visible and understandable.
Examples of colour pairs
Black on white is 21 to 1, the maximum. Dark grey #595959 on white is 7.0 to 1, which meets AAA. Grey #767676 on white is 4.54 to 1, which passes AA. Light grey #999999 on white is 2.85 to 1, which fails even the large text threshold.
Pure red #ff0000 on white is 4.0 to 1: it fails for normal text but passes for large text. White text on an orange of #ff4a1f is 3.36 to 1, suitable only for large text, while black text on the same orange is 6.25 to 1, which passes for all sizes. A deep blue #0b5cad on white is 6.67 to 1.
These show a common trap with brand colours. Bright, saturated colours often work better as backgrounds with dark text, or as accents, than as text colours on white. If a brand orange fails with white text, try dark text on it or use a darker shade for small text.
How to fix low contrast
The simplest fix is to darken the text colour or lighten the background until the ratio passes. Small steps are often enough: moving from #999999 to #767676 turns a failing grey into a passing one while looking only slightly darker.
Keep the design intent by using the colour somewhere else, such as a heading at a large size where the lower threshold applies, or a border or a background tint. For text on photographs, add a solid or semi-transparent panel behind the text so the contrast does not depend on what part of the image sits underneath.
Check all states of the design: hover, focus, visited links, error messages, placeholders in form fields and buttons. Placeholder text is often very pale, and error text in red on a pink background is a common failure. Check dark mode too, because the same colours may behave differently on a dark background.
What contrast does not cover
A passing ratio is necessary but not enough. Do not use colour as the only way to give information. A red error and a green success that differ only in colour are indistinguishable to someone with red-green colour blindness. Add an icon, a label or an underline.
Text size, font weight, line spacing and line length also affect readability. Thin fonts at small sizes are hard to read even when the ratio passes. Links within text should be identifiable without relying on colour alone, for example by underlining.
Finally, test with real people where you can. Zoom the page to 200 per cent, view it on a phone outdoors, and ask someone who uses assistive technology to try the key tasks. A tool gives you a number, and people tell you whether the page works.
Tools mentioned in this guide
Colour Contrast Checker
Check the contrast ratio between two colours against WCAG 2.2 and get a nearby colour that passes.
ConvertersColour Converter
Convert HEX, RGB and HSL colours and check text contrast.
ImagesColour Blindness Simulator
See how colours and pictures look with protanopia, deuteranopia, tritanopia and no colour vision.
SEO & websitesAccessibility Checker
Find common accessibility problems in a web page, with a fix for each.
Included with UnlimitedCreate & convertColour Palette Generator
Build a matching colour palette from one base colour, then copy the codes or export CSS variables.
ImagesColour Picker from Image
Click any pixel to get HEX, RGB and HSL, and pull a 6 colour palette from the picture.
Frequently asked questions
What contrast ratio do I need for text?
At WCAG level AA, 4.5 to 1 for normal text and 3 to 1 for large text. Level AAA asks for 7 to 1 and 4.5 to 1.
What counts as large text?
At least 18 point (24 pixels), or at least 14 point (about 18.7 pixels) if bold.
Does contrast apply to buttons and form borders?
Yes. WCAG 2.1 asks for at least 3 to 1 for interface components and graphics that convey meaning, such as the outline of a text field.
Is black text on an orange background acceptable?
Often yes. Black on #ff4a1f is 6.25 to 1, which passes AA and AAA for normal text. White on the same orange is only 3.36 to 1.
Do logos have to meet the contrast rules?
No. Text that is part of a logo or brand name is exempt, as is purely decorative content.