Accessibility

Colour contrast ratios: what WCAG requires and how to fix them

WCAG asks for 4.5:1 for body text, 3:1 for large text and controls, and 7:1 at AAA. How the ratio works, what is exempt, and brand-safe fixes.

By Co-Founder and Design Director, ZeeFrames

7 min read

Short answer

At Level AA, WCAG asks for a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (1.4.3), and 3:1 for the parts of controls and graphics people need to see (1.4.11). Large text means at least 18pt (24px), or 14pt bold (about 18.66px). The stricter Level AAA asks for 7:1, or 4.5:1 for large text (1.4.6).

Low contrast is the most common accessibility failure on the web. The WebAIM Million 2026 found low-contrast text on 83.9% of the top million home pages, up from 79.1% in 2025, with an average of 34 distinct instances per page (WebAIM, 2026). It is also one of the easiest failures to fix once you know the numbers. This post explains the ratios, how they are worked out, what is exempt, and how to fix a failing colour without throwing away your brand.

The contrast ratios at a glance

Minimum contrast ratios in WCAG 2.2. Source: W3C, WCAG 2.2
WhatLevel AALevel AAACriterion
Normal text and images of text4.5:17:11.4.3 (AA), 1.4.6 (AAA)
Large text: 18pt (24px), or 14pt (about 18.66px) bold3:14.5:11.4.3 (AA), 1.4.6 (AAA)
Visual parts of controls and their states: borders, checkmarks, focus rings3:1No higher level1.4.11
Parts of graphics needed to understand them: chart lines, meaningful icons3:1No higher level1.4.11
Logos, disabled controls, pure decorationNo requirementNo requirement1.4.3, 1.4.11 exceptions

How is the contrast ratio calculated?

The ratio compares the relative luminance of two colours, which is how bright each one is on a scale from 0 for black to 1 for white. The formula is (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter colour and L2 the darker. The result runs from 1:1, the same colour twice, to 21:1, black on white.

Relative luminance weights the red, green and blue channels differently, with green counting most: L = 0.2126 R + 0.7152 G + 0.0722 B, after each channel is converted from its 0 to 255 value to a linear one. You do not need to do this by hand. Any contrast checker, such as the free one from WebAIM, does it for you.

Two details catch people out. First, the thresholds are exact: W3C says computed values should not be rounded, so 4.499:1 does not meet 4.5:1. Grey #777777 on white is 4.48:1 and fails for body text, while #767676 is 4.54:1 and passes. Second, contrast is measured against the background the text sits on in normal use, and if you set a text colour you need to set a background colour too.

What counts as large text?

WCAG defines large-scale text as at least 18 point, or at least 14 point bold. CSS sets 1pt equal to 1.333px, so 18pt is 24px and 14pt is about 18.66px. W3C rounds that second figure to roughly 18.5px in its Understanding page; if your bold text sits between the two, make it 19px to be safe.

The size that counts is the size the page is delivered at, not what someone gets by zooming. W3C also warns that very thin or unusual fonts are harder to read at lower contrast, so a light-weight display font at 24px can pass on paper and still be hard to read.

In practice: Headlines and hero text usually qualify for 3:1. Body copy, captions, form labels, placeholder text and button text at normal sizes need 4.5:1. W3C notes that placeholder text and text shown on hover or focus are covered too.

Contrast for buttons, inputs, icons and charts (1.4.11)

Success criterion 1.4.11 Non-text Contrast, added in WCAG 2.1, asks for 3:1 against adjacent colours for two kinds of thing. The first is the visual information needed to identify a control and its state: an input border, a checkbox outline, the check inside it, a toggle track, a focus ring. The second is the parts of a graphic someone needs to understand it, such as the lines in a chart or an icon that carries meaning.

A border is not always required. W3C's Understanding page says that if a control already has visible text or a contrasting icon that shows it is there, its outer boundary does not have to meet 3:1. Where nothing else marks the control, as with a text input on a white page, the border does. W3C's own passing example is a #767676 border on white, and its focus-ring example is #949494 on white at 3:1.

Colour contrast is separate from colour meaning. Under 1.4.1 Use of Color, colour must not be the only way you show information, so a red border on an invalid field also needs an icon or message.

What is exempt from contrast rules?

  • Logos and brand names. Text in a logo or brand name has no contrast requirement. W3C still encourages a passing version where the logo is a link or control.
  • Inactive controls. Disabled buttons and fields have no requirement under 1.4.3 or 1.4.11. A grey "Submit" button that unlocks once the form is filled in is W3C's own example.
  • Pure decoration. Text that is purely decorative, or not visible to anyone, has no requirement.
  • Text inside a picture. Text that is part of a picture containing significant other visual content, such as a sign in a street photo, has no requirement.
  • Browser defaults. Under 1.4.11, controls whose look is set by the browser and not changed by you are exempt.

These are narrower than they look. Light grey helper text, a pale footer and a "decorative" headline that carries the page's message are not exempt. Low-contrast text is one of the barriers commonly cited in ADA website lawsuits.

This post is general information, not legal advice. Meeting the contrast ratios is one part of WCAG conformance, not a guarantee against claims.

How to fix a failing colour without wrecking the brand

Most contrast failures come from one brand colour being used for everything. You rarely need a new palette. You need the same hue at a few lightness levels, each with a clear job.

  1. Keep the hue, change the lightness. Darken the colour until it passes on your background. The brand still reads as the same colour; it is just deeper.
  2. Split the colour into roles. A bright blue such as #3B82F6 is 3.68:1 on white. That passes for large text, icons and input borders, but fails for body text and small button labels. #2563EB is 5.17:1 and passes for both. Use the bright one for big shapes and the deeper one for text and small buttons.
  3. Check orange and yellow first. Bright oranges and yellows are high in luminance, so they struggle on white. Orange #FF6B00 on white is 2.86:1, short of even 3:1, while a burnt orange such as #C2410C reaches 5.18:1.
  4. Flip the pairing. If white text on your brand colour fails, try dark text on it. The ratio for a pair is the same whichever colour is on top, so the fix is often a darker label rather than a darker button.
  5. Protect text on images. Put a dark overlay behind the text, or a solid panel. Then the text still passes when someone swaps the photo.
  6. Test every state. Check hover, focus, visited, error and placeholder colours, not just the default. Dark mode needs its own check.

Making text bold or bigger only helps if it crosses the large-text line. A 16px label made bold is still normal text and still needs 4.5:1.

What ProCurveUX checks, and what needs a person

ProCurveUX measures the colours your page actually renders in a real browser, against the background each element really sits on. Its contrast checks are:

  • "Body text contrast below minimum" for normal text under 4.5:1. It skips disabled text, logos and text hidden from assistive technology as decorative, as WCAG does.
  • "Large text contrast below minimum" for large text under 3:1.
  • "UI component boundary contrast below minimum" for input borders, toggle tracks, checkbox outlines and icon-only controls under 3:1.
  • "Focus indicator contrast insufficient" for focus rings under 3:1 against the component or the page.
  • "Text over image without contrast protection" for text on a photo with no overlay, where any sampled point falls under 4.5:1.

Each finding gives the measured ratio, and body-text findings name both colours and suggest the nearest shade that passes. The sample report shows the format. A person still has to judge the edge cases: whether text is truly decorative, which parts of a chart or illustration someone needs to understand it, and whether colour is the only thing carrying a meaning. ProCurveUX has a check for that last one, "Information conveyed by color alone", but it is a judgement call worth confirming by eye. For the rest of the standard, see our accessibility checklist and what changed in WCAG 2.2.

Frequently asked questions

At Level AA, 4.5:1 for normal text, 3:1 for large text and 3:1 for user interface components and meaningful graphics. At Level AAA, 7:1 for normal text and 4.5:1 for large text.

References

  1. W3C, Web Content Accessibility Guidelines (WCAG) 2.2, 1.4.3, 1.4.6, 1.4.11 and the definitions of contrast ratio, relative luminance and large scale text
  2. W3C Web Accessibility Initiative, Understanding SC 1.4.3 Contrast (Minimum)
  3. W3C Web Accessibility Initiative, Understanding SC 1.4.6 Contrast (Enhanced)
  4. W3C Web Accessibility Initiative, Understanding SC 1.4.11 Non-text Contrast
  5. WebAIM, The WebAIM Million: The 2026 report on the accessibility of the top 1,000,000 home pages, February 2026 data
  6. WebAIM, Contrast Checker, free tool for checking a colour pair

More from the blog

Your next customer is one fix away.
Find it in 60 seconds.

Your first audit is free. See exactly what's holding your site back before your next release.

Analyze my websiteView a real audit

Just your email · No card · No install