Colour Contrast Accessibility: WCAG Ratios, Rules and Practical Fixes
The exact contrast ratios WCAG asks for, what counts as large text, which states and elements are covered, and how to fix a brand palette that falls short.
Get a manual WCAG auditColour contrast accessibility comes down to a few numbers. Under WCAG Level AA, normal body text needs a contrast ratio of at least 4.5:1 against its background. Large text (18 point, or 14 point bold) needs at least 3:1. Icons, form field borders, focus indicators and the meaningful parts of charts need at least 3:1 against the colours next to them. And colour can never be the only way you show information, such as which field has an error.
Low contrast is still one of the most common problems we find on websites, usually because a pale grey looked fine on a good monitor, a brand colour was approved before anyone measured it, or a hover state or a line of text over a photo was never checked.
This guide covers every WCAG color contrast requirement (US spelling, same standard), how the ratio is calculated, the exemptions people get wrong, how to test with a contrast checker or your browser's developer tools, and how to repair a brand palette without throwing it away.
WCAG contrast ratio requirements at a glance
Four success criteria deal with colour. The last column matters for Ontario organizations: the AODA's legal baseline is WCAG 2.0 Level AA, so a criterion added in WCAG 2.1 isn't part of that legal minimum, even though it's in the current standard and many procurement requirements. Our overview of AODA requirements and deadlines explains who has to meet what.
| Success criterion | Level | What it covers | Minimum | In WCAG 2.0? |
|---|---|---|---|---|
| 1.4.1 Use of Color | A | Colour is not the only visual means of conveying information | No ratio; needs a second cue | Yes |
| 1.4.3 Contrast (Minimum) | AA | Text and images of text | 4.5:1 normal text, 3:1 large text | Yes |
| 1.4.6 Contrast (Enhanced) | AAA | Text and images of text | 7:1 normal text, 4.5:1 large text | Yes |
| 1.4.11 Non-text Contrast | AA | UI components, states, focus indicators and meaningful graphics | 3:1 against adjacent colours | No (added in 2.1) |
How the WCAG contrast ratio is calculated
The contrast ratio compares the relative luminance (perceived brightness) of two colours. 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 (identical colours) to 21:1 (black on white). Hue doesn't enter into it: a red and a green of similar brightness can look very different to some people and still score close to 1:1, and that is exactly the kind of pair many people with colour vision deficiencies can't tell apart.
Two details catch people out. First, the ratio is not rounded. W3C's guidance is explicit that 4.499:1 does not meet 4.5:1. Second, if you set a text colour without a background colour (or the other way round), you are relying on the user's defaults, and W3C treats that as a failure. Specify both.
#767676 on white: 4.54:1, the lightest neutral grey that passes for body text.
#777777 on white: 4.48:1, which fails, even though the two greys are indistinguishable to most eyes.
#999999 on white: 2.85:1, a common "subtle" grey that fails for text of any size.
4.5:1 contrast for text (1.4.3)
Success criterion 1.4.3 applies to all text and images of text: body copy, headings, links, button labels, form labels, captions, table data and text baked into graphics. Normal text needs 4.5:1; large text needs 3:1.
What counts as large text
WCAG defines large-scale text as at least 18 point, or at least 14 point bold. W3C's Understanding document gives the CSS equivalents as approximately 24px and approximately 18.5px bold (using 1pt = 1.333px). A 20px semibold subheading or a 16px bold button label is not large text. When in doubt, hold it to 4.5:1.
What's exempt, and what isn't
WCAG sets no contrast requirement for:
- Text in an inactive (disabled) user interface component, such as a disabled button or form field.
- Purely decorative text, and text that isn't visible to anyone.
- Incidental text in a photo that has significant other visual content, like a street sign.
- Logotypes: text that is part of a logo or brand name.
The logotype exception covers the logo itself, not your brand colour used everywhere else. And while disabled controls are exempt, a disabled button so faint that users can't tell it exists is still a usability problem.
Hover, focus and placeholder text are included
The criterion explicitly covers placeholder text and text shown when a pointer hovers over an element or when it has keyboard focus. Light grey placeholder text in a form field is one of the most frequent failures we see; it needs 4.5:1 like any other text. The same goes for a button whose label turns pale on hover, or a menu item that changes colour on focus. Check every state, not just the resting one. Our guide to accessible form fields covers why placeholders shouldn't replace labels in the first place.
Enhanced contrast (1.4.6, AAA)
Level AAA raises the bar to 7:1 for normal text and 4.5:1 for large text. It isn't required by the AODA or by typical procurement clauses, and W3C advises against requiring Level AAA as a general policy for entire sites. It's still a sensible target for long-form reading content, and for text that people with low vision rely on, like instructions and error messages.
Non-text contrast: UI components and graphics (1.4.11)
Non-text contrast asks for 3:1 between a component's essential visual parts and the colours next to them. "Essential" is the key word: it's the visual information someone needs to identify a control or understand its state.
- Form field borders. If the border is the only thing that shows where a text input is, it needs 3:1 against the page. A #CCCCCC border on white is 1.61:1 and fails; #949494 is 3.03:1 and passes.
- Icons that carry meaning, such as a search icon or a close (X) button without a text label.
- State indicators: the check mark in a checkbox, the dot in a selected radio button, the thumb of a toggle switch.
- Custom focus indicators. Combined with 2.4.7 Focus Visible, a focus ring you design must reach 3:1 against what's around it. The browser's default focus ring is exempt from the ratio, but it must still be visible.
- Charts and diagrams: lines, bars and pie slices needed to understand the data, against the background and, where they touch, against each other.
A few things are not required. A button with readable text doesn't need a contrasting border: the text already identifies it (although a visible boundary helps many users). Author-added hover effects are treated as supplemental, because the mouse pointer already shows where you are, as long as hovering doesn't reduce contrast. Disabled components and unstyled browser-default controls are exempt.
Use of colour (1.4.1): never rely on colour alone
Use of Color is a Level A requirement, so it's in the AODA baseline. It doesn't set a ratio; it says colour can't be the only visual way to convey information, show an action, prompt a response or distinguish an element. Common failures:
- Links in body text that differ from surrounding text only by colour. W3C technique G183 accepts this only when the link colour has at least 3:1 contrast with the surrounding text. A #0066CC link in #333333 body copy is 2.27:1 against the text and fails. An underline is the simplest fix.
- Form errors shown only by turning a border red. Add an icon and an error message in text.
- Charts where the legend maps series to colours with nothing else. Add direct labels, patterns or different marker shapes.
- Status badges that are green, amber or red with no word. Write "Passed", "Needs review", "Failed".
Text over images and gradients
Hero banners with headline text on a photograph are a contrast trap, because the background changes from pixel to pixel and from one screen size to the next as the image crops differently. W3C lists insufficient contrast between text and a background image as a failure (F83). Measure against the lightest part of the image behind light text, or the darkest part behind dark text, at every breakpoint.
The dependable fix is to put a solid or semi-opaque layer between the image and the text, so the worst case is predictable. For example, a 60% black overlay turns even a pure white area of a photo into roughly #666666, which gives white text 5.74:1:
.hero {
background-color: #1f2937; /* fallback if the image fails to load */
background-image:
linear-gradient(rgb(0 0 0 / 0.6), rgb(0 0 0 / 0.6)),
url('/images/hero.jpg');
background-size: cover;
color: #ffffff;
}The fallback background colour matters too: if the image doesn't load, white text on a white page is invisible. Other good options are a solid text panel, or placing the text beside the image instead of on it. Gradients follow the same logic: test the text against the lightest point of the gradient it overlaps.
Not sure where your site's contrast falls short?
A manual audit checks every state, overlay and component that automated tools skip, and tells you exactly which colours to change.
See our WCAG auditHow to check contrast: tools and devtools
Use a contrast checker
A contrast checker takes two colours and reports the ratio against each WCAG threshold. The WebAIM Contrast Checker works in the browser if you have hex values. TPGi's free Colour Contrast Analyser is a desktop app with an eyedropper, which is useful for text over images, PDFs and anything you can't inspect as code.
Use your browser's developer tools
In Chrome or Edge, use Inspect on a text element: the hover tooltip shows its contrast ratio, and the colour picker in the Styles pane shows the ratio plus the lines where AA and AAA are met, so you can drag to a passing shade. Firefox's Accessibility Inspector can check a whole page for contrast issues. Chrome's Rendering panel can also emulate colour vision deficiencies.
Combine automated and manual checks
An automated accessibility scan is good at finding plain text on solid backgrounds that fails 4.5:1, across many pages quickly. It generally can't judge text over images, gradients, hover and focus states, non-text contrast or whether colour alone carries meaning. Those need a person. We explain the split in more depth in automated vs manual accessibility testing.
Fixing a brand palette without losing the brand
Bright, saturated brand colours often fail as text on white. The fix is rarely to abandon the colour; it's to give each colour a clear job and add the shades it needs.
Brand orange #FF7A00 with white text: 2.61:1. Fails for text of every size, and fails 3:1 for UI components.
Same orange with black text: 8.04:1. Passes AAA. Keep the orange button, change the label colour.
Darker orange #B35400 on white: 5.02:1. Use this shade for orange text and links.
- Measure every pairing you actually use, not every colour on its own. A colour doesn't pass or fail; a combination does.
- Separate fill colours from text colours. Keep the bright brand shade for large surfaces, illustrations and backgrounds, and pair it with whichever text colour passes.
- Add darker (or lighter) steps of each brand colour for text, links and borders.
- Document approved pairs in your design system or style guide, with their ratios, so new pages don't reintroduce failures.
What about WCAG 3 and APCA?
You may have read that WCAG 3 will replace the contrast ratio with a new method, often associated with the Accessible Perceptual Contrast Algorithm (APCA). WCAG 3 is a W3C Working Draft, not a standard, and the current draft states that its contrast algorithm is yet to be determined. It is not a requirement anywhere. The AODA, Canadian federal standards and procurement documents reference WCAG 2.x, so the 4.5:1 and 3:1 ratios are what you're measured against. Don't use APCA in place of the WCAG 2 ratio when compliance is the goal.
Colour contrast accessibility checklist
- Body text, links and labels reach 4.5:1 against their background.
- Only text at 24px+ (or about 18.5px+ bold) uses the 3:1 large-text threshold.
- Placeholder, hover and focus states are checked, not just the resting state.
- Text over images or gradients passes at its worst point, at every breakpoint.
- Input borders, meaningful icons and checkbox and radio states reach 3:1.
- Custom focus indicators reach 3:1 against adjacent colours.
- Chart elements reach 3:1 and don't rely on colour alone.
- Links in body text are underlined or otherwise distinguished without colour.
- Errors and statuses use text or icons as well as colour.
- Approved colour pairings are documented for the whole team.
For the rest of the criteria, our WCAG 2.2 AA accessibility checklist walks through each one. The full W3C explanation of 1.4.3 is in the Understanding Contrast (Minimum) document, and non-text contrast is covered in Understanding Non-text Contrast.
Frequently asked questions
What is the minimum colour contrast ratio for WCAG AA?
4.5:1 for normal text and 3:1 for large text (at least 18 point, or 14 point bold). User interface components and meaningful graphics need 3:1 against adjacent colours.
Do disabled buttons need to meet contrast requirements?
No. WCAG exempts inactive user interface components from both text and non-text contrast. Make sure people can still tell the control exists and understand why it's unavailable.
Does the AODA require non-text contrast?
Not as a legal minimum. The AODA's baseline is WCAG 2.0 Level AA, and non-text contrast (1.4.11) was added in WCAG 2.1. Text contrast (1.4.3) and use of colour (1.4.1) are required. Many contracts and procurement documents ask for WCAG 2.1 or 2.2, which include 1.4.11.
Does placeholder text need 4.5:1 contrast?
Yes. W3C's guidance on 1.4.3 explicitly includes placeholder text. Pale grey placeholders are a common failure.
Do logos have to meet contrast requirements?
No. Text that is part of a logo or brand name is exempt. The exception covers the logo itself, not brand colours used for other text on the page.