WCAG Color Contrast Requirements Explained: AA, AAA, and the Non-Text Rule Most Teams Miss
A complete map of WCAG 2.2 contrast success criteria — SC 1.4.3 (text), SC 1.4.6 (AAA), and SC 1.4.11 (non-text UI) — with real hex examples, the five legal exemptions, and how to fix every failure type.
WCAG Color Contrast Requirements Explained: AA, AAA, and the Non-Text Rule Most Teams Miss
Most developers learn one number — 4.5:1 — and assume that covers every WCAG contrast obligation. It covers roughly one third of them. WCAG 2.2 contains three distinct contrast success criteria, each governing a different class of UI element, and the WebAIM Million 2024 report found that 83.6% of home pages across the top one million websites have at least one detectable WCAG 2 failure, with low contrast being the single most common violation. This guide maps all three criteria to the specific components they apply to, shows a real audit run on actual hex codes, walks through the five exemptions that let you legally skip the requirement, and explains the edge cases — gradients, placeholders, hover states — that bite teams on the second audit.
The Three Contrast Criteria: Which Rule Applies to What
WCAG 2.2 splits contrast obligations across three success criteria. Understanding which criterion applies to which element prevents both over-engineering (requiring 7:1 on a disabled button) and under-engineering (ignoring a form field outline).
SC 1.4.3 — Contrast Minimum (Level AA) This is the baseline legal requirement. It requires:
- 4.5:1 for normal text (below 18 pt regular or 14 pt bold)
- 3:1 for large text (at or above 18 pt regular, or 14 pt bold — roughly 24 px and 18.67 px at standard browser zoom)
"Normal text" is the default. If you aren't sure a paragraph, label, or link qualifies as large, it's normal and needs 4.5:1.
SC 1.4.6 — Contrast Enhanced (Level AAA) The same thresholds, raised:
- 7:1 for normal text
- 4.5:1 for large text
AAA is aspirational and explicitly not required at site-wide scale. WCAG's own guidance notes that some valid color identities (brand reds, certain teals) cannot reach 7:1 against both white and black backgrounds simultaneously, making site-wide AAA an impossible constraint. Target AAA for your most critical reading: body copy in healthcare apps, financial disclosures, error messages.
SC 1.4.11 — Non-Text Contrast (Level AA) This is the forgotten rule. It requires 3:1 contrast between:
- Visual information necessary to identify a UI component (button border, text input outline, checkbox) and the adjacent background color
- States of UI components: focus rings, selected tabs, active toggle positions
- Parts of graphics required to understand the content: chart axes, data point markers, infographic icons
A grey form field outline on a white background — a near-universal design pattern — commonly fails this criterion even when all the text inside it passes 1.4.3.
What Actually Counts as "Large Text"
The 3:1 large-text threshold is generous enough that people abuse it. The formal definition has two parts:
- At least 18 pt (24 px) in regular weight, or
- At least 14 pt (~18.67 px) in bold (CSS
font-weight: 700or higher)
Several common mistakes:
font-weight: 600(semibold) does not qualify as bold for WCAG purposes. The spec says bold, meaning a weight that "looks substantially thicker" than regular — in practice, auditors and automated tools treat 700+ as bold.- A heading rendered at 22 px regular does not qualify as large text. It needs to hit 24 px or be set to bold at ≥ 18.67 px.
- CSS pixels, not device pixels. A 24 px heading on a 2× retina display is still 24 CSS px, and the contrast requirement stays 3:1.
The Five Exemptions You Can Actually Use
WCAG explicitly lists elements that are excluded from the contrast requirements. Knowing these prevents wasted effort on elements that can legally have any color:
- Inactive UI components — A disabled button, greyed-out menu item, or read-only field in a locked state has no contrast obligation. The user cannot interact with it, so failing to see it is acceptable.
- Decorative text and images — Text that is purely decorative (a watermark, a texture made of repeated letters) and conveys no information is exempt. If removing it would not affect comprehension, it's decorative.
- Logotypes — Text that is part of a logo or brand name is explicitly excluded. Your product name in its branded color sits outside every WCAG contrast check.
- Invisible text — Text that is invisible (zero opacity, hidden with CSS, behind another element) has no contrast requirement.
- Photos and rich images — Text embedded in a photograph is exempt. A caption rendered in white over a complex photo background is not required to pass, because the background luminance varies pixel by pixel. (Though best practice is still to add a text shadow or semi-transparent scrim.)
Real Audit: Three Color Pairs, Three Different Failures
I recently ran a quick audit on a common design pattern — a card UI with a body paragraph, a primary button, and a form field. Here are the exact pairs and what I found using the Color Contrast Checker.
Pair 1 — Body text on card background
- Foreground:
#6B7280(a popular "muted" gray from Tailwind 500) - Background:
#FFFFFF - Ratio: 4.48:1
- SC 1.4.3 AA normal text: ❌ FAIL (needs 4.5:1 — misses by 0.02)
A coin flip. This is one of the most common real-world failures because Tailwind's gray-500 sits just below the threshold. Swapping to gray-600 (#4B5563) gets you to 7.0:1 — AAA for free.
Pair 2 — Primary button label on brand blue
- Foreground:
#FFFFFF - Background:
#3B82F6(Tailwindblue-500) - Ratio: 3.0:1
- SC 1.4.3 AA normal text: ❌ FAIL
- SC 1.4.3 AA large text: ✅ PASS (barely)
White text on medium blue is almost never AA-compliant at body sizes. Switching to blue-600 (#2563EB) brings the ratio to 4.77:1 — passing AA for all text sizes.
Pair 3 — Input field border on white
- Border:
#D1D5DB(Tailwindgray-300) - Background:
#FFFFFF - Ratio: 1.59:1
- SC 1.4.11 non-text UI: ❌ FAIL (needs 3:1)
The text inside the field might be perfectly legible, but the border that defines the field's boundary fails 1.4.11. The fix: use at least gray-400 (#9CA3AF) for borders that need to be visible as component boundaries, giving you 2.85:1 — still marginal. gray-500 (#6B7280) at 4.48:1 clears the 3:1 threshold comfortably.
For any failing pair, the WCAG Color Contrast Fixer auto-generates four adjusted colors that hit your target level while preserving the original hue — useful when you want the closest compliant alternative without redefining a brand color.
Edge Cases That Fail Second Audits
Placeholders: Placeholder text in form inputs (the ::placeholder pseudo-element) is subject to the same 4.5:1 rule as normal text. A common design pattern is to render placeholder text at 30–40% opacity against a white background — this almost always fails. Placeholder text needs to either have sufficient intrinsic contrast or be labeled as decorative, but since it communicates the field's purpose, it's rarely decorative.
Gradient backgrounds: WCAG does not have explicit guidance for text on gradients. The practical approach auditors use: measure the worst-performing point of the text-background region. If any part of the background shifts enough that the text-to-background ratio drops below threshold, the text fails.
Focus indicators: SC 2.4.11 (WCAG 2.2, Level AA) introduces minimum size and contrast requirements for focus indicators specifically — the focus ring must have at least 3:1 contrast against the surrounding color. Many default browser outlines pass; custom CSS focus rings in brand colors often don't.
Text on images: Even though background photographs are exempt, a translucent colored overlay on a photo behind text is not fully exempt. If the overlay has a defined color, auditors treat that overlay-background pair as testable.
Testing Order That Saves Time
Run contrast checks in this sequence to fix the most failures for the least effort:
- Check all body text and link colors first — these touch the most words.
- Check button labels and form input text — high interaction frequency means failures here are most impactful.
- Check UI component boundaries (borders, outlines, dividers) — SC 1.4.11 failures are often systemic across a design system.
- Check focus rings manually — automated tools miss these more often than text failures.
- Apply exemptions last — confirm disabled states and decorative elements before marking anything as N/A.
The Color Contrast Checker runs all five WCAG success criteria in a single pass (SC 1.4.3 AA, SC 1.4.3 large, SC 1.4.6 AAA, SC 1.4.6 large, SC 1.4.11) so you see the full picture from one color pair, not three separate lookups.
Made by Toolora · Updated 2026-06-25