WCAG success criteria beyond color contrast: a holistic approach to accessibility
YYYY-03-Mar 16, 2026 · Jamie Chen
Color contrast gets most of the attention in accessibility conversations. It's measurable, it's concrete, and tools make it easy to check. But here's what I've learned from eight years of auditing enterprise SaaS products: teams that obsess over contrast ratios while ignoring everything else are building half-accessible experiences.
WCAG 2.2 contains 93 success criteria across four principles—Perceivable, Operable, Understandable, and Robust. Color contrast is just one of them. The criteria that actually fail most projects are the ones nobody talks about: keyboard navigation that doesn't work, focus indicators that vanish, form labels that are invisible to screen readers, motion that triggers seizures, language so jargon-heavy that users with cognitive disabilities can't follow it.
This post is about the criteria that matter most—and how to implement them systematically so you're not building ramps for people with mobility disabilities while leaving everyone else stuck at the door.
The WCAG framework: what you're actually working with
Before we go deeper, let's establish the map. WCAG 2.2 is organized around four principles—often remembered by the acronym POUR:
Perceivable: Users must be able to see, hear, or otherwise detect the information being presented. This includes color contrast, but also text alternatives for images, captions for videos, and making content distinguishable from the background.
Operable: Users must be able to interact with your interface using whatever input method they have—keyboard, mouse, switch device, voice control. If you've hidden your navigation behind a mouse-only hover state, it's not operable.
Understandable: Users must comprehend your content and know how to use your interface. This covers readable language, predictable navigation, form error messages that actually explain what went wrong, and instructions that don't require you to have a PhD.
Robust: Your code must be solid enough that assistive technologies—screen readers, voice control software, browser extensions—can reliably interpret it. This is where semantic HTML, proper ARIA, and valid markup live.
Color contrast falls under Perceivable. But it's competing for attention with 19 other perceivable criteria. Most of them will affect your users more directly.
Keyboard navigation: the foundation everything else rests on
Let's start here because keyboard accessibility is non-negotiable and it's impossible to fake.
Success Criterion 2.1.1 (Keyboard) requires that all functionality available via mouse must also be available via keyboard. This means:
- Every interactive element (buttons, links, form fields, dropdowns, modals) must receive focus
- Focus must follow a logical tab order
- There must be a visible focus indicator so users know where they are
- Escape should close dialogs and modals
I audit products where developers have spent weeks perfecting hover states that only work with a mouse. Then they discover 10% of their user base relies entirely on keyboard navigation—people with motor disabilities, older users, power users who never touch a trackpad, people using accessibility switches. And none of those users can access critical features.
Here's the honest truth: if your product doesn't work with a keyboard, your WCAG rating is already in the basement. Contrast ratio or not.
The implementation: Use semantic HTML as your foundation. Native <button>, <a>, and <input> elements are keyboard-accessible out of the box. If you're building custom components with divs and spans, you're replicating accessibility work that already exists.
<!-- ✓ Native button—keyboard accessible by default -->
<button type="button" aria-label="Close menu">×</button>
<!-- ✗ Custom div button—requires manual focus management, keyboard handlers -->
<div role="button" tabindex="0">×</div>
If you must use role="button", add tabindex="0" and handle the Enter and Space keys. Better: don't. Use <button>.
For focus visible indicators, don't remove the default outline:
/* ✗ Common mistake—removes focus visibility entirely */
button:focus {
outline: none;
}
/* ✓ Replace the default with something visible and on-brand */
button:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
Note the :focus-visible pseudo-class. This fires only when keyboard or switch device is used—not mouse. It lets you have clean mouse UX while protecting keyboard users.
Focus management and skip links: getting people to the content
Criterion 2.4.1 (Bypass Blocks) requires that users can skip repetitive content. On a multi-page site, this usually means a skip-to-main-content link that appears at the very top of every page and jumps focus past the header and navigation.
Why? Because a keyboard user who visits 50 pages in your site has now tabbed through 50 navigation menus. Fifty times. Skip links let them jump straight to the new content.
<body>
<!-- Skip link—always the first focusable element -->
<a href="#main" class="skip-link">Skip to main content</a>
<header>
<nav>
<!-- Your navigation here -->
</nav>
</header>
<main id="main" tabindex="-1">
<!-- Page content starts here -->
</main>
</body>
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
The skip link is visually hidden until focused—then it becomes visible. A keyboard user hits Tab once and can immediately jump to main content. A mouse user never sees it.
And that tabindex="-1" on the main element? It lets you programmatically move focus there without making the element part of the tab order. This is called focus management, and it's essential for single-page applications and modal dialogs.
Form labels and error handling: the criteria most projects fail
I've audited 200+ enterprise products. I'd say 70% of them have form labels connected to their inputs using only visual proximity—no actual label element, no aria-label, no aria-labelledby. The label and the input look connected to a sighted user, but a screen reader user has no idea what they're typing into.
Criterion 1.3.1 (Info and Relationships) and Criterion 3.3.1 (Error Identification) cover this. Labels must be programmatically associated with inputs.
<!-- ✓ Proper label association -->
<label for="email">Email address</label>
<input id="email" type="email" name="email" />
<!-- ✗ Visual proximity isn't enough -->
<div>Email address</div>
<input type="email" name="email" />
<!-- ✓ When a label can't be visible, use aria-label -->
<input type="search" aria-label="Search products" placeholder="Search..." />
And when validation fails—when a user submits a form with an invalid email or missing required field—you must:
- Programmatically associate the error message with the input
- Make the error message visible to screen reader users
- Return focus to the field that has the error
<div>
<label for="email">Email address</label>
<input
id="email"
type="email"
name="email"
aria-describedby="email-error"
aria-invalid="true"
/>
<span id="email-error" role="alert">
Please enter a valid email address
</span>
</div>
The aria-describedby attribute connects the error message to the input. The role="alert" tells the screen reader to announce this immediately. The aria-invalid="true" tells assistive technology that this field has an error.
Most of the time, I see inputs with visual red borders and error text floating nearby. Sighted users understand immediately. A screen reader user? They have no idea.
Headings and document structure: the invisible architecture
Criterion 1.3.1 also covers proper use of headings. Your page must have a logical heading hierarchy—H1 at the top, then H2s, then H3s. No skipping levels like H1 → H3 → H2.
This isn't about aesthetics. It's about creating an invisible outline that screen reader users navigate by. Think of it like a table of contents. If the outline is broken, users can't understand the structure of your content.
<!-- ✓ Logical hierarchy -->
<h1>Product features</h1>
<h2>Data visualization</h2>
<h3>Real-time dashboards</h3>
<h3>Custom reports</h3>
<h2>Collaboration tools</h2>
<h3>Team workspaces</h3>
<!-- ✗ Skipped levels—confusing to navigate -->
<h1>Product features</h1>
<h3>Data visualization</h3>
<h3>Custom reports</h3>
I recommend thinking of your heading structure before you write a single line of HTML. Map out your page like a document outline. Then build the HTML to match.
Text alternatives: beyond alt text
Criterion 1.1.1 (Non-text Content) says all images, videos, and graphical elements must have text alternatives. Most teams know about alt text for images. What they miss is everything else:
- Videos: Captions (for Deaf users and people in noisy environments) and descriptive audio tracks (for blind users)
- Icons: If an icon conveys meaning—a trash icon as a delete button—it needs either a visible label or an aria-label
- Charts and graphs: A simple alt text like "sales chart" is useless. Users need a text summary or a data table
- Decorative images: These get
alt=""to hide them from screen readers
<!-- ✓ Icon button with aria-label -->
<button aria-label="Delete item">
<svg><!-- trash icon --></svg>
</button>
<!-- ✗ Icon button with no label -->
<button>
<svg><!-- trash icon --></svg>
</button>
<!-- ✓ Meaningful alt text for data visualization -->
<img
src="sales-2024.png"
alt="Sales by quarter: Q1 $500K, Q2 $620K, Q3 $710K, Q4 $890K"
/>
<!-- ✗ Vague alt text -->
<img src="sales-2024.png" alt="chart" />
Motion, animation, and seizure prevention
Criterion 2.3.3 (Animation from Interactions) and 2.3.1 (Three Flashes) are about preventing content that could trigger seizures or cause vestibular issues.
If your interface uses:
- Flashing content: Nothing should flash more than 3 times per second
- Rapid motion or scrolling: Animations with sudden changes can trigger vertigo in people with vestibular disorders
- Auto-playing videos or background animations: Users should be able to stop them
And critically, users should be able to globally disable motion through a media query:
@media (prefers-reduced-motion: respect) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
If a user has set "Reduce motion" in their OS settings, this CSS disables your animations. You're respecting their preference, not forcing motion sickness.
Language and readability: making content understandable
Criterion 3.1.1 (Language of Page) requires that the language of your content be declared. Criterion 3.1.5 (Reading Level) says if your content requires reading comprehension above secondary education level, you should provide a simplified version or a glossary.
But here's what I see constantly: documentation written for internal engineers, every sentence buried in jargon, abbreviations used without definition.
<!-- ✓ Language declared -->
<html lang="en">
<!-- ✗ No language declaration -->
<html>
And in your content:
<!-- ✗ Unclear and jargon-heavy -->
Implement OAuth 2.0 bearer token validation in your JWT middleware to mitigate CSRF vulnerabilities across SPA deployments.
<!-- ✓ Clear and accessible -->
To secure your app, use login tokens (called OAuth) that expire after a set time. This prevents hackers from accessing data if they steal a token.
Criterion 2.5.3 (Label in Name) also fits here: if you have a button that says "Submit," the label must include the word "submit" so that voice control users can invoke it by saying "submit."
Link text and context
Criterion 2.4.4 (Link Purpose) requires that the purpose of every link is clear from the link text alone—or from the surrounding context.
<!-- ✗ Vague link text -->
<p>Check out our new accessibility guide <a href="/guide">here</a>.</p>
<!-- ✓ Clear link text -->
<p><a href="/guide">Check out our new accessibility guide</a>.</p>
<!-- ✓ Or, if the surrounding context is clear enough -->
<p>We published an accessibility guide.
<a href="/guide">Read the full guide</a></p>
A screen reader user listening to a list of all links on your page will hear "here," "click here," "read more," "link"—none of which tell them where the link goes. Make the link text itself descriptive.
Putting it together: a checklist for auditing your product
Here's a practical framework for evaluating whether your product is actually accessible across WCAG criteria—not just color contrast:
Perceivable:
- Color contrast meets WCAG AA minimum (4.5:1 for text, 3:1 for graphics)
- All images have descriptive alt text; decorative images have
alt="" - Videos have captions and audio descriptions
- Content is distinguishable from background (not just relying on color)
- Resizable text works without loss of content or functionality
Operable:
- All functionality works with keyboard alone—no mouse required
- Focus is visible and follows a logical tab order
- Skip links allow users to bypass repetitive navigation
- No content traps—users can tab away from any element
- Touch targets are at least 24x24 CSS pixels (Criterion 2.5.5)
Understandable:
- Form labels are properly associated with inputs
- Error messages are descriptive and linked to the problematic field
- Navigation is predictable—menus behave the same way on every page
- Language is clear; jargon is explained or avoided
- Instructions and help are readily available
Robust:
- Semantic HTML is used correctly; roles, states, and properties are valid
- ARIA is used to augment, not replace, semantic HTML
- The page is compatible with major browsers and assistive technologies
- Links and buttons have accessible names
Why color contrast still matters—but isn't the whole story
I don't want to undersell color contrast. It matters enormously. If your color contrast is poor, roughly 8% of men and 1% of women will have a harder time reading your text. Add low contrast to tiny fonts, and you've excluded everyone from age 50 onward who doesn't wear glasses.
But here's the thing: a user with low vision can see your page if the contrast is good. Then they tab to a form and discover there's no way to navigate it with the keyboard. They can't see it, and now they can't use it either.
A user with a motor disability might never need to see your page at all—they use a screen reader. If your images don't have alt text, your videos don't have captions, and your form labels are invisible to assistive technology, that user is locked out completely.
Color contrast + keyboard navigation + form labels + text alternatives + clear language = accessibility. Leave any one of these out and you've broken the chain.
When to bring in a professional accessibility audit
If you're building a product that serves the public—a SaaS tool, a government site, a health app—you should have a professional accessibility audit before launch and then annually. Not because you can't do accessibility testing in-house, but because an experienced auditor will catch things your team won't.
They'll test with real assistive technology users. They'll spot focus management issues in your single-page app. They'll find form errors that only appear under specific conditions. They'll catch the obscure WCAG criteria that your automated testing tool missed.
The cost of an audit is a fraction of the cost of rebuilding your product after launch when disabled users can't use it and you're facing legal pressure.
FAQ
Q: Do I have to meet all 93 success criteria?
A: Most organizations target WCAG 2.2 Level AA, which covers the most impactful criteria. Level AAA (the highest level) is recommended for government and health sites. Criterion 2.4.8 (Focus Visible) is non-negotiable—I don't care what your budget is.
Q: If I use semantic HTML and test with a screen reader, am I accessible?
A: Screen readers are just one assistive technology. Test with actual keyboard-only users, people using voice control, people with motor disabilities, people with cognitive disabilities, and people with color blindness. Diversity of testers beats any single tool.
Q: Can I use automated testing tools to check WCAG compliance?
A: Automated tools are great for catching low-hanging fruit—missing alt text, color contrast, missing form labels. But they catch maybe 30% of real accessibility issues. The rest require manual testing and human judgment. Don't rely on automated tools alone.
Q: Is WCAG just for disabled people?
A: Absolutely not. Accessible design helps everyone. Clear language helps people reading in a second language. Keyboard navigation helps power users. Captions help people in noisy environments. Resizable text helps older users. Good accessibility is good UX.
Q: What's the legal risk if I don't comply with WCAG?
A: In the US, inaccessible digital products can trigger lawsuits under the Americans with Disabilities Act (ADA). In the UK and EU, there are accessibility regulations (EN 301 549) with similar teeth. Compliance reduces legal risk, but more importantly, it lets disabled people use your product.
Related Articles
- Color accessibility best practices for web designers
- How to use a color blindness simulator (for images & websites)
- Testing your website for color blindness accessibility
If you're building a product and want to see how it performs across color vision deficiencies and other accessibility dimensions, take a screenshot and run it through our WCAG contrast checker and color blindness simulator—it's free and works entirely in your browser.
Test your designs against all four CVD types right now with DeficiencyView's color blindness simulator — upload any image or enter a URL and see results in seconds.