Skip to main content
Back to Blog
Accessibility

WCAG 2.2 Compliance Checklist: Complete 2025 Implementation Roadmap

Master WCAG 2.2 compliance with our comprehensive checklist covering all 86 success criteria. Includes new 2.2 requirements, implementation priorities, testing protocols, and free downloadable compliance tracker.

AllAccessible Team
40 min read
WCAG 2.2ComplianceWeb AccessibilityADASection 508Accessibility Checklist
WCAG 2.2 Compliance Checklist: Complete 2025 Implementation Roadmap

WCAG 2.2 Compliance Checklist: Complete 2025 Implementation Roadmap

Last Updated: November 20, 2025 | Reading Time: 18 minutes

WCAG 2.2 became the official W3C standard on October 5, 2023, adding 9 new success criteria to the existing framework. With the European Accessibility Act (EAA) now in force since June 28, 2025, and ongoing ADA litigation in the U.S., achieving WCAG 2.2 Level AA compliance is no longer optional—it's a business imperative.

This comprehensive guide provides an actionable checklist covering all 86 success criteria across WCAG 2.2 Levels A and AA, with prioritized implementation roadmaps, real-world code examples, and testing protocols.


Executive Summary

What's New in WCAG 2.2:

  • 9 new success criteria (6 at Level AA, 3 at Level A)
  • Focus on mobile accessibility, cognitive disabilities, and low vision users
  • Backward compatible with WCAG 2.1 (no criteria removed)
  • Stricter requirements for authentication, help mechanisms, and focus visibility

Business Impact:

  • Legal Risk: 73% of ADA website lawsuits in 2024 referenced WCAG 2.1 AA (UsableNet)
  • EU Enforcement: EAA compliance now mandatory since June 28, 2025 for EU businesses
  • Market Expansion: 1 in 4 adults in the U.S. has a disability (CDC)
  • SEO Benefit: Accessible sites rank higher due to improved UX metrics

Implementation Timeline:

  • Immediate (Week 1-2): Critical WCAG 2.2 Level A compliance
  • Short-term (Month 1-3): Full Level AA compliance
  • Ongoing: Continuous monitoring and remediation

Table of Contents

  1. WCAG 2.2 Overview
  2. What's New in WCAG 2.2
  3. Complete WCAG 2.2 AA Checklist
  4. Prioritized Implementation Roadmap
  5. Testing and Validation
  6. Common Compliance Gaps
  7. Legal and Regulatory Context
  8. Downloadable Resources

WCAG 2.2 Overview

What is WCAG 2.2?

Web Content Accessibility Guidelines (WCAG) 2.2 is the latest W3C recommendation for making web content accessible to people with disabilities, including:

  • Visual impairments (blindness, low vision, color blindness)
  • Hearing impairments (deafness, hard of hearing)
  • Motor impairments (limited dexterity, tremors)
  • Cognitive disabilities (learning disabilities, memory issues)
  • Neurological conditions (epilepsy, ADHD)

WCAG Structure

WCAG is organized into 4 principles (POUR):

  1. Perceivable: Information must be presentable to users in ways they can perceive
  2. Operable: User interface components must be operable
  3. Understandable: Information and UI must be understandable
  4. Robust: Content must be robust enough to work with assistive technologies

Conformance Levels

  • Level A: Minimum accessibility (25 criteria)
  • Level AA: Recommended standard for legal compliance (38 additional criteria = 63 total)
  • Level AAA: Enhanced accessibility (23 additional criteria = 86 total)

Most regulations require Level AA compliance (ADA, Section 508, EAA).


What's New in WCAG 2.2

9 New Success Criteria

Level A Criteria (3 new)

2.4.11 Focus Not Obscured (Minimum) - Level AA (Wait, this is AA) 2.5.7 Dragging Movements - Level AA (This is AA too) 2.5.8 Target Size (Minimum) - Level AA (Also AA)

Let me correct this:

Level A Criteria (3 new)

3.3.7 Redundant Entry - Level A

  • Users shouldn't have to enter the same information twice in a process
  • Autocomplete or pre-fill previously entered data
  • Critical for checkout flows and multi-step forms

Example:

<!-- BAD: Forces users to re-enter shipping address for billing -->
<fieldset>
  <legend>Billing Address</legend>
  <label for="billing-street">Street Address</label>
  <input type="text" id="billing-street" name="billing_street" />
  <!-- User must manually re-type address -->
</fieldset>

<!-- GOOD: Provides option to use same address -->
<fieldset>
  <legend>Billing Address</legend>
  <label>
    <input type="checkbox" id="same-as-shipping" checked />
    Same as shipping address
  </label>
  <div id="billing-fields" style="display:none;">
    <label for="billing-street">Street Address</label>
    <input
      type="text"
      id="billing-street"
      name="billing_street"
      autocomplete="billing street-address"
    />
  </div>
</fieldset>

<script>
document.getElementById('same-as-shipping').addEventListener('change', function(e) {
  document.getElementById('billing-fields').style.display =
    e.target.checked ? 'none' : 'block';
});
</script>

3.3.8 Accessible Authentication (Minimum) - Level AA (This is AA)

Let me recategorize correctly:

Level AA Criteria (6 new)

2.4.11 Focus Not Obscured (Minimum) - Level AA

  • Keyboard focus indicator must not be completely hidden by author-created content
  • Prevents sticky headers/footers from blocking focused elements
  • Critical for keyboard-only users

Example:

/* BAD: Sticky header obscures focused elements */
.sticky-header {
  position: fixed;
  top: 0;
  z-index: 1000;
  /* When user tabs down page, focused elements go under header */
}

/* GOOD: Ensure sufficient scroll padding */
html {
  scroll-padding-top: 100px; /* Height of sticky header + buffer */
}

/* GOOD: Ensure focus indicator is never obscured */
*:focus {
  outline: 3px solid #0066CC;
  outline-offset: 2px;
  scroll-margin-top: 120px; /* Ensures element scrolls into view with clearance */
}

2.4.12 Focus Not Obscured (Enhanced) - Level AAA

2.4.13 Focus Appearance - Level AAA

2.5.7 Dragging Movements - Level AA

  • Functionality requiring dragging must have an alternative (click, keyboard)
  • Critical for drag-and-drop interfaces, sliders, sortable lists
  • Helps users with motor impairments

Example:

<!-- BAD: Drag-only slider -->
<div class="slider" draggable="true">
  <div class="slider-handle"></div>
</div>

<!-- GOOD: Slider with keyboard and click alternatives -->
<label for="volume-slider">Volume</label>
<input
  type="range"
  id="volume-slider"
  min="0"
  max="100"
  value="50"
  aria-valuemin="0"
  aria-valuemax="100"
  aria-valuenow="50"
  aria-label="Volume control"
/>
<!-- Native range input supports keyboard (arrow keys) and click -->

<!-- GOOD: Sortable list with keyboard alternative -->
<ul role="list" aria-label="Task list (use Up/Down arrows to reorder)">
  <li role="listitem" tabindex="0" draggable="true">
    <button aria-label="Move task up">↑</button>
    <button aria-label="Move task down">↓</button>
    Task 1
  </li>
</ul>

2.5.8 Target Size (Minimum) - Level AA

  • Interactive targets must be at least 24×24 CSS pixels
  • Exception: inline links in sentences can be smaller
  • Critical for mobile users and those with motor impairments

Example:

/* BAD: Small touch targets */
.icon-button {
  width: 16px;
  height: 16px;
  padding: 0;
}

/* GOOD: Minimum 24×24px targets */
.icon-button {
  min-width: 24px;
  min-height: 24px;
  padding: 4px; /* Visual icon can be 16×16, but clickable area is 24×24 */
}

/* GOOD: Larger targets for primary actions */
.primary-button {
  min-width: 44px;
  min-height: 44px;
  padding: 12px 24px;
}

/* Exception: inline links */
p a {
  /* Can be smaller than 24px when in paragraph text */
  text-decoration: underline;
  padding: 0.25em 0; /* But add vertical padding for easier clicking */
}

3.2.6 Consistent Help - Level A

  • Help mechanisms must appear in same relative order across pages
  • Examples: chat widget, help link, contact form
  • Reduces cognitive load for users with learning disabilities

Example:

<!-- BAD: Help link moves around -->
<!-- Page 1: Help in header -->
<header>
  <nav>
    <a href="/help">Help</a>
  </nav>
</header>

<!-- Page 2: Help in footer (different location) -->
<footer>
  <a href="/help">Help</a>
</footer>

<!-- GOOD: Consistent help placement -->
<!-- All pages: Help in same spot in header -->
<header>
  <nav aria-label="Main navigation">
    <a href="/">Home</a>
    <a href="/products">Products</a>
    <a href="/help">Help</a> <!-- Always last item in main nav -->
  </nav>
</header>

<!-- GOOD: Fixed help widget (always bottom-right) -->
<button
  class="help-widget"
  style="position: fixed; bottom: 20px; right: 20px;"
  aria-label="Open help chat"
>
  <svg aria-hidden="true"><!-- chat icon --></svg>
  Help
</button>

3.3.7 Redundant Entry - Level A

  • Previously covered above

3.3.8 Accessible Authentication (Minimum) - Level AA

  • Cognitive function tests (remembering passwords, solving puzzles) must have alternatives
  • Allow password managers, email/SMS verification, or biometric authentication
  • Critical for users with cognitive disabilities

Example:

<!-- BAD: CAPTCHA with no alternative -->
<form>
  <label for="captcha">Enter the text shown:</label>
  <img src="/captcha.jpg" alt="CAPTCHA image" />
  <input type="text" id="captcha" required />
</form>

<!-- GOOD: Provide alternative authentication -->
<form>
  <fieldset>
    <legend>Verify you're human</legend>

    <!-- Option 1: Email verification code -->
    <label>
      <input type="radio" name="auth-method" value="email" checked />
      Email me a verification code
    </label>

    <!-- Option 2: reCAPTCHA v3 (invisible, no user interaction) -->
    <label>
      <input type="radio" name="auth-method" value="recaptcha" />
      Automatic verification
    </label>
  </fieldset>

  <!-- Allow password managers -->
  <label for="password">Password</label>
  <input
    type="password"
    id="password"
    autocomplete="current-password"
    aria-describedby="password-help"
  />
  <p id="password-help">Your browser can save this password for you</p>
</form>

3.3.9 Accessible Authentication (Enhanced) - Level AAA


Complete WCAG 2.2 AA Checklist

Principle 1: Perceivable

1.1 Text Alternatives

1.1.1 Non-text Content (Level A)

  • All images have alt text
  • Decorative images have empty alt (alt="")
  • Complex images have long descriptions
  • Form inputs have accessible labels

Implementation:

<!-- Informative image -->
<img src="chart.png" alt="Sales increased 45% in Q4 2024" />

<!-- Decorative image -->
<img src="border.png" alt="" role="presentation" />

<!-- Complex image with long description -->
<figure>
  <img src="org-chart.png" alt="Company organizational chart"
       aria-describedby="org-description" />
  <figcaption id="org-description">
    The chart shows CEO Jane Smith at the top, with three VP reports:
    VP Engineering (John Doe), VP Sales (Mary Johnson), VP Marketing (Bob Wilson).
  </figcaption>
</figure>

<!-- Form input with label -->
<label for="email">Email Address</label>
<input type="email" id="email" name="email" required />

1.2 Time-based Media

1.2.1 Audio-only and Video-only (Prerecorded) (Level A)

  • Audio-only content has transcript
  • Video-only content has audio description or transcript

1.2.2 Captions (Prerecorded) (Level A)

  • All prerecorded videos have captions
  • Captions are synchronized with audio
  • Captions include speaker identification and sound effects

1.2.3 Audio Description or Media Alternative (Prerecorded) (Level A)

  • Videos have audio description OR text transcript

1.2.4 Captions (Live) (Level AA)

  • Live audio content has real-time captions
  • Live video has synchronized captions

1.2.5 Audio Description (Prerecorded) (Level AA)

  • Videos have audio description for visual content
  • Description explains visual context not in dialogue

Implementation:

<video controls>
  <source src="presentation.mp4" type="video/mp4" />
  <track kind="captions" src="captions-en.vtt" srclang="en" label="English" default />
  <track kind="descriptions" src="descriptions-en.vtt" srclang="en" label="English descriptions" />
  <p>Your browser doesn't support HTML5 video.
     <a href="transcript.html">Read the transcript</a>
  </p>
</video>

1.3 Adaptable

1.3.1 Info and Relationships (Level A)

  • Semantic HTML used correctly (headings, lists, tables)
  • Programmatic relationships defined with ARIA when needed
  • Form fields associated with labels

1.3.2 Meaningful Sequence (Level A)

  • Content order makes sense when linearized
  • Tab order follows logical reading sequence
  • CSS doesn't disrupt visual order from DOM order

1.3.3 Sensory Characteristics (Level A)

  • Instructions don't rely solely on shape, size, or location
  • Visual cues supplemented with text
  • Color not the only way to convey information

1.3.4 Orientation (Level AA)

  • Content works in portrait and landscape
  • No orientation lock unless essential
  • Responsive design supports all orientations

1.3.5 Identify Input Purpose (Level AA)

  • Form inputs have autocomplete attributes
  • Input types match expected data
  • Helps autofill and assistive technologies

Implementation:

<!-- 1.3.1: Semantic structure -->
<article>
  <h1>Main Heading</h1>
  <p>Introduction paragraph</p>

  <h2>Section 1</h2>
  <ul>
    <li>List item 1</li>
    <li>List item 2</li>
  </ul>

  <table>
    <caption>Sales Data</caption>
    <thead>
      <tr>
        <th scope="col">Month</th>
        <th scope="col">Revenue</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>January</td>
        <td>$50,000</td>
      </tr>
    </tbody>
  </table>
</article>

<!-- 1.3.3: Don't rely on sensory characteristics -->
<!-- BAD -->
<p>Click the green button on the right to continue</p>

<!-- GOOD -->
<p>Click the "Continue" button to proceed to checkout</p>
<button class="continue-button" style="background: green; float: right;">
  Continue
</button>

<!-- 1.3.5: Autocomplete for input purpose -->
<form>
  <label for="name">Full Name</label>
  <input type="text" id="name" name="name" autocomplete="name" />

  <label for="email">Email</label>
  <input type="email" id="email" name="email" autocomplete="email" />

  <label for="tel">Phone</label>
  <input type="tel" id="tel" name="tel" autocomplete="tel" />

  <label for="address">Street Address</label>
  <input type="text" id="address" name="address" autocomplete="street-address" />

  <label for="city">City</label>
  <input type="text" id="city" name="city" autocomplete="address-level2" />

  <label for="state">State</label>
  <input type="text" id="state" name="state" autocomplete="address-level1" />

  <label for="zip">ZIP Code</label>
  <input type="text" id="zip" name="zip" autocomplete="postal-code" />

  <label for="cc-number">Credit Card Number</label>
  <input type="text" id="cc-number" name="cc-number" autocomplete="cc-number" />

  <label for="cc-exp">Expiration Date</label>
  <input type="text" id="cc-exp" name="cc-exp" autocomplete="cc-exp" />
</form>

1.4 Distinguishable

1.4.1 Use of Color (Level A)

  • Color is not the only way to convey information
  • Links distinguishable from text without color
  • Form errors indicated with icons/text, not just red borders

1.4.2 Audio Control (Level A)

  • Auto-playing audio can be paused
  • Audio controls provided for background sounds
  • Volume control available

1.4.3 Contrast (Minimum) (Level AA)

  • Text has 4.5:1 contrast ratio (normal text)
  • Large text (18pt+ or 14pt+ bold) has 3:1 ratio
  • UI components and graphics have 3:1 contrast

1.4.4 Resize Text (Level AA)

  • Text can be resized to 200% without loss of content or functionality
  • No horizontal scrolling at 200% zoom
  • Layout reflows gracefully

1.4.5 Images of Text (Level AA)

  • Real text used instead of images of text (where possible)
  • Exception: logos, essential visual presentation

1.4.10 Reflow (Level AA)

  • No horizontal scrolling at 320px width (mobile)
  • No vertical scrolling at 256px height
  • Content reflows for 400% zoom
  • Exception: maps, diagrams requiring 2D layout

1.4.11 Non-text Contrast (Level AA)

  • UI components have 3:1 contrast against background
  • Graphical objects have 3:1 contrast
  • Focus indicators have sufficient contrast

1.4.12 Text Spacing (Level AA)

  • Content readable with custom text spacing:
    • Line height 1.5× font size
    • Paragraph spacing 2× font size
    • Letter spacing 0.12× font size
    • Word spacing 0.16× font size

1.4.13 Content on Hover or Focus (Level AA)

  • Tooltip/popup content dismissible (Esc key)
  • Hoverable (mouse can move over popup without closing)
  • Persistent (doesn't disappear automatically)

Implementation:

/* 1.4.3: Color contrast */
body {
  background: #FFFFFF;
  color: #333333; /* 12.6:1 contrast ratio - exceeds 4.5:1 */
}

.link {
  color: #0066CC; /* 7.0:1 contrast - exceeds 4.5:1 */
  text-decoration: underline; /* Don't rely on color alone */
}

/* 1.4.4: Resize text */
html {
  font-size: 16px; /* Base font size */
}

body {
  font-size: 1rem; /* Use relative units */
}

h1 {
  font-size: 2rem; /* Scales with user preferences */
}

/* 1.4.10: Reflow */
@media (max-width: 400px) {
  .container {
    width: 100%;
    overflow-x: hidden; /* Prevent horizontal scroll */
  }

  .grid {
    display: block; /* Stack grid items vertically */
  }
}

/* 1.4.11: Non-text contrast */
button {
  background: #0066CC;
  border: 2px solid #004499; /* 3:1 contrast between bg and border */
  color: #FFFFFF;
}

input:focus {
  outline: 3px solid #0066CC; /* 3:1+ contrast against white background */
  outline-offset: 2px;
}

/* 1.4.12: Text spacing support */
* {
  /* Don't restrict text spacing */
  line-height: inherit !important;
  letter-spacing: inherit !important;
  word-spacing: inherit !important;
}

/* Test with this CSS to verify no content breaks: */
/*
* {
  line-height: 1.5 !important;
  letter-spacing: 0.12em !important;
  word-spacing: 0.16em !important;
}

p {
  margin-bottom: 2em !important;
}
*/

/* 1.4.13: Hover/focus content */
.tooltip {
  position: absolute;
  /* Ensure tooltip is hoverable */
  pointer-events: auto;
}

.tooltip-trigger:hover + .tooltip,
.tooltip:hover {
  display: block;
}

/* Dismissible with Esc key */
.tooltip[aria-hidden="false"] {
  display: block;
}
// 1.4.13: Dismissible tooltips with Esc key
document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape') {
    const openTooltips = document.querySelectorAll('.tooltip[aria-hidden="false"]');
    openTooltips.forEach(tooltip => {
      tooltip.setAttribute('aria-hidden', 'true');
    });
  }
});

Principle 2: Operable

2.1 Keyboard Accessible

2.1.1 Keyboard (Level A)

  • All functionality available via keyboard
  • No keyboard traps
  • Custom widgets keyboard-navigable

2.1.2 No Keyboard Trap (Level A)

  • User can move focus away from all components
  • Standard Esc/Arrow keys work to exit modals/menus
  • Focus can move freely through page

2.1.4 Character Key Shortcuts (Level A)

  • Single-key shortcuts can be turned off or remapped
  • Only active when component has focus
  • Alternative activation method provided

Implementation:

<!-- 2.1.1: Keyboard accessible custom widget -->
<div
  role="button"
  tabindex="0"
  onclick="doAction()"
  onkeydown="if(event.key === 'Enter' || event.key === ' ') { doAction(); event.preventDefault(); }"
  aria-label="Save document"
>
  Save
</div>

<!-- 2.1.2: No keyboard trap - modal example -->
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Action</h2>
  <p>Are you sure you want to delete this item?</p>
  <button>Cancel</button>
  <button>Delete</button>
</div>

<script>
// Trap focus within modal
const modal = document.querySelector('[role="dialog"]');
const focusableElements = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
const firstFocusable = focusableElements[0];
const lastFocusable = focusableElements[focusableElements.length - 1];

modal.addEventListener('keydown', function(e) {
  // Allow Esc to close modal (no trap)
  if (e.key === 'Escape') {
    closeModal();
    return;
  }

  // Cycle focus within modal
  if (e.key === 'Tab') {
    if (e.shiftKey && document.activeElement === firstFocusable) {
      e.preventDefault();
      lastFocusable.focus();
    } else if (!e.shiftKey && document.activeElement === lastFocusable) {
      e.preventDefault();
      firstFocusable.focus();
    }
  }
});
</script>

2.2 Enough Time

2.2.1 Timing Adjustable (Level A)

  • User can turn off, adjust, or extend time limits
  • Warning before timeout with option to extend
  • Exception: real-time events (auctions)

2.2.2 Pause, Stop, Hide (Level A)

  • Auto-updating content can be paused
  • Carousels have pause button
  • Scrolling text can be stopped

Implementation:

<!-- 2.2.1: Session timeout warning -->
<div role="alertdialog" aria-labelledby="timeout-title" aria-live="assertive">
  <h2 id="timeout-title">Session Expiring Soon</h2>
  <p>Your session will expire in <span id="countdown">60</span> seconds due to inactivity.</p>
  <button onclick="extendSession()">Stay Logged In</button>
  <button onclick="logout()">Log Out</button>
</div>

<script>
let timeoutWarningShown = false;
let sessionTimeout = 30 * 60 * 1000; // 30 minutes
let warningTimeout = 29 * 60 * 1000; // 29 minutes

function showTimeoutWarning() {
  if (!timeoutWarningShown) {
    timeoutWarningShown = true;
    document.querySelector('[role="alertdialog"]').style.display = 'block';

    let countdown = 60;
    const countdownEl = document.getElementById('countdown');
    const interval = setInterval(() => {
      countdown--;
      countdownEl.textContent = countdown;
      if (countdown <= 0) {
        clearInterval(interval);
        logout();
      }
    }, 1000);
  }
}

function extendSession() {
  // Reset timers
  clearTimeout(warningTimer);
  clearTimeout(sessionTimer);
  startTimers();
  timeoutWarningShown = false;
  document.querySelector('[role="alertdialog"]').style.display = 'none';
}

function startTimers() {
  warningTimer = setTimeout(showTimeoutWarning, warningTimeout);
  sessionTimer = setTimeout(logout, sessionTimeout);
}

startTimers();
</script>

<!-- 2.2.2: Pausable carousel -->
<div class="carousel" role="region" aria-label="Featured products" aria-live="polite">
  <button onclick="toggleCarousel()" aria-label="Pause carousel">
    <span class="pause-icon" aria-hidden="true">⏸</span>
    <span class="play-icon" style="display:none;" aria-hidden="true">▶</span>
  </button>

  <div class="carousel-items">
    <div class="carousel-item active">Item 1</div>
    <div class="carousel-item">Item 2</div>
    <div class="carousel-item">Item 3</div>
  </div>

  <button onclick="prevSlide()" aria-label="Previous slide">←</button>
  <button onclick="nextSlide()" aria-label="Next slide">→</button>
</div>

2.3 Seizures and Physical Reactions

2.3.1 Three Flashes or Below Threshold (Level A)

  • No content flashes more than 3 times per second
  • Flashing content below general/red flash thresholds
  • Animations can be disabled

Implementation:

/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Don't create flashing content */
.notification {
  /* BAD: Flashing animation */
  /* animation: flash 0.2s infinite; */

  /* GOOD: Subtle fade-in */
  animation: fadeIn 0.5s ease-in;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

2.4 Navigable

2.4.1 Bypass Blocks (Level A)

  • "Skip to main content" link provided
  • Heading structure allows navigation
  • ARIA landmarks define page regions

2.4.2 Page Titled (Level A)

  • Every page has descriptive <title>
  • Title identifies page purpose/context
  • Title format: Page Name - Site Name

2.4.3 Focus Order (Level A)

  • Tab order is logical and predictable
  • Focus follows visual layout
  • No unexpected focus jumps

2.4.4 Link Purpose (In Context) (Level A)

  • Link text describes destination
  • No "click here" or "read more" without context
  • Links distinguishable by more than color

2.4.5 Multiple Ways (Level AA)

  • At least two ways to find pages (menu, search, sitemap)
  • Site search available
  • Breadcrumb navigation or sitemap provided

2.4.6 Headings and Labels (Level AA)

  • Headings describe topic or purpose
  • Form labels clearly describe inputs
  • Instructions precede form fields

2.4.7 Focus Visible (Level AA)

  • Keyboard focus indicator always visible
  • Focus indicator has sufficient contrast
  • Focus indicator not removed by CSS

2.4.11 Focus Not Obscured (Minimum) (Level AA) ⭐ NEW IN 2.2

  • Focused element not completely hidden by sticky headers/footers
  • At least part of focus indicator visible
  • Scroll padding prevents obscured focus

Implementation:

<!-- 2.4.1: Skip link -->
<a href="#main-content" class="skip-link">Skip to main content</a>

<header>
  <nav aria-label="Main navigation">
    <!-- navigation -->
  </nav>
</header>

<main id="main-content" tabindex="-1">
  <!-- main content -->
</main>

<style>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}
</style>

<!-- 2.4.2: Descriptive page title -->
<title>Checkout - Step 2: Shipping Information - AllAccessible Store</title>

<!-- 2.4.4: Descriptive link text -->
<!-- BAD -->
<a href="/report.pdf">Click here</a> to download the report

<!-- GOOD -->
<a href="/report.pdf">Download the 2024 Annual Report (PDF, 2MB)</a>

<!-- 2.4.6: Descriptive headings -->
<h1>Account Settings</h1>

<h2>Personal Information</h2>
<p>Update your name, email, and contact details</p>

<h2>Password & Security</h2>
<p>Change your password and manage two-factor authentication</p>

<h2>Notification Preferences</h2>
<p>Control which emails and alerts you receive</p>

<!-- 2.4.7 & 2.4.11: Visible, unobscured focus -->
<style>
html {
  scroll-padding-top: 100px; /* Height of sticky header */
}

*:focus {
  outline: 3px solid #0066CC;
  outline-offset: 2px;
  scroll-margin-top: 120px; /* Ensures focused element scrolls with clearance */
}

/* Never remove focus indicator */
*:focus:not(:focus-visible) {
  /* If you must style differently for mouse users, keep a visible indicator */
  outline: 2px solid #999;
}
</style>

2.5 Input Modalities

2.5.1 Pointer Gestures (Level A)

  • Multipoint gestures have single-point alternative
  • Path-based gestures have simple alternative
  • Pinch-to-zoom has buttons

2.5.2 Pointer Cancellation (Level A)

  • Down-event doesn't trigger action
  • Action triggered on up-event
  • Prevents accidental activation

2.5.3 Label in Name (Level A)

  • Visible label text included in accessible name
  • Voice control users can activate by visible label
  • Icon buttons have accessible names matching visible tooltips

2.5.4 Motion Actuation (Level A)

  • Shake/tilt gestures have UI alternative
  • Motion-triggered features can be disabled
  • Button alternative for device motion

2.5.7 Dragging Movements (Level AA) ⭐ NEW IN 2.2

  • Drag-and-drop has single-pointer alternative
  • Sortable lists have up/down buttons
  • Sliders work with keyboard and click

2.5.8 Target Size (Minimum) (Level AA) ⭐ NEW IN 2.2

  • Interactive targets at least 24×24 CSS pixels
  • Exception: inline links can be smaller
  • Spacing between targets sufficient

Implementation:

<!-- 2.5.1: Single-point alternative to pinch-zoom -->
<div class="image-viewer">
  <img src="photo.jpg" alt="Product photo" id="zoomable-image" />
  <div class="zoom-controls">
    <button onclick="zoomIn()" aria-label="Zoom in">+</button>
    <button onclick="zoomOut()" aria-label="Zoom out">−</button>
    <button onclick="resetZoom()" aria-label="Reset zoom">Reset</button>
  </div>
</div>

<!-- 2.5.3: Label in name -->
<!-- BAD: Visible text doesn't match accessible name -->
<button aria-label="Submit form">
  Send <!-- Screen reader announces "Submit form" but voice user says "Click Send" -->
</button>

<!-- GOOD: Accessible name includes visible text -->
<button aria-label="Send message">
  Send
</button>

<!-- 2.5.7: Dragging alternative -->
<ul class="sortable-list" role="list">
  <li role="listitem" draggable="true" tabindex="0">
    <span class="handle" aria-hidden="true">⋮⋮</span>
    <button onclick="moveUp(this)" aria-label="Move item up">↑</button>
    <button onclick="moveDown(this)" aria-label="Move item down">↓</button>
    <span>Task 1</span>
  </li>
  <li role="listitem" draggable="true" tabindex="0">
    <span class="handle" aria-hidden="true">⋮⋮</span>
    <button onclick="moveUp(this)" aria-label="Move item up">↑</button>
    <button onclick="moveDown(this)" aria-label="Move item down">↓</button>
    <span>Task 2</span>
  </li>
</ul>

<!-- 2.5.8: Minimum target size -->
<style>
.icon-button {
  min-width: 24px;
  min-height: 24px;
  padding: 4px;
  margin: 4px; /* Spacing between targets */
}

/* Primary actions should be even larger */
.primary-action {
  min-width: 44px;
  min-height: 44px;
  padding: 12px 24px;
}
</style>

Principle 3: Understandable

3.1 Readable

3.1.1 Language of Page (Level A)

  • Page language declared in HTML
  • Correct lang attribute on <html> tag
  • Helps screen readers pronounce correctly

3.1.2 Language of Parts (Level AA)

  • Language changes marked with lang attribute
  • Foreign phrases tagged
  • Multilingual content properly identified

Implementation:

<!-- 3.1.1: Page language -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Welcome to AllAccessible</title>
</head>
<body>
  <h1>Welcome</h1>

  <!-- 3.1.2: Language of parts -->
  <p>Our company motto is <span lang="fr">Liberté, Égalité, Accessibilité</span></p>

  <blockquote lang="es">
    <p>La accesibilidad es un derecho, no un privilegio.</p>
    <footer>— Accessibility advocate</footer>
  </blockquote>
</body>
</html>

3.2 Predictable

3.2.1 On Focus (Level A)

  • Focus doesn't trigger unexpected context changes
  • Focus doesn't auto-submit forms
  • Focus doesn't open new windows automatically

3.2.2 On Input (Level A)

  • Changing inputs doesn't cause unexpected changes
  • Form submission requires explicit action
  • Radio button selection doesn't auto-navigate

3.2.3 Consistent Navigation (Level AA)

  • Navigation menus in same order across pages
  • Consistent header/footer layout
  • Predictable site structure

3.2.4 Consistent Identification (Level AA)

  • Icons/buttons have consistent labels across site
  • Same functionality labeled identically
  • Print icon always means "print"

3.2.6 Consistent Help (Level A) ⭐ NEW IN 2.2

  • Help mechanisms appear in same order across pages
  • Chat widget, help link, contact form consistent
  • Reduces cognitive load

Implementation:

<!-- 3.2.1: Focus doesn't change context -->
<!-- BAD: Focus opens popup -->
<input
  type="text"
  onfocus="openPopup()" <!-- Unexpected behavior -->
/>

<!-- GOOD: User explicitly triggers popup -->
<input type="text" id="search" />
<button onclick="openSearchHelp()">Search Help</button>

<!-- 3.2.2: Input doesn't change context -->
<!-- BAD: Radio selection auto-navigates -->
<label>
  <input type="radio" name="lang" value="es" onchange="window.location='/es/'" />
  Español
</label>

<!-- GOOD: Explicit submit button -->
<form>
  <label>
    <input type="radio" name="lang" value="es" />
    Español
  </label>
  <button type="submit">Change Language</button>
</form>

<!-- 3.2.6: Consistent help placement -->
<!-- Every page has help in same location -->
<header>
  <nav aria-label="Main navigation">
    <a href="/">Home</a>
    <a href="/products">Products</a>
    <a href="/about">About</a>
    <a href="/help">Help</a> <!-- Always last item -->
  </nav>
</header>

3.3 Input Assistance

3.3.1 Error Identification (Level A)

  • Form errors identified in text
  • Error messages describe the error
  • Required fields indicated before submission

3.3.2 Labels or Instructions (Level A)

  • Form fields have labels
  • Instructions provided for complex inputs
  • Format requirements explained

3.3.3 Error Suggestion (Level AA)

  • Error messages suggest corrections
  • Provide examples of correct format
  • Help users fix errors

3.3.4 Error Prevention (Legal, Financial, Data) (Level AA)

  • Reversible: Allow undo
  • Checked: Validate before submission
  • Confirmed: Require explicit confirmation for critical actions

3.3.7 Redundant Entry (Level A) ⭐ NEW IN 2.2

  • Don't make users re-enter same information
  • Autocomplete previous entries
  • Copy shipping to billing option

3.3.8 Accessible Authentication (Minimum) (Level AA) ⭐ NEW IN 2.2

  • Cognitive function tests have alternatives
  • Password managers supported
  • Email/SMS verification option for CAPTCHA

Implementation:

<!-- 3.3.1: Error identification -->
<form novalidate> <!-- Use custom validation for better error messages -->
  <div class="form-group">
    <label for="email">
      Email Address
      <span class="required" aria-label="required">*</span>
    </label>
    <input
      type="email"
      id="email"
      name="email"
      required
      aria-required="true"
      aria-invalid="true"
      aria-describedby="email-error"
    />
    <span id="email-error" class="error" role="alert">
      Please enter a valid email address (example: you@example.com)
    </span>
  </div>

  <!-- 3.3.2: Labels and instructions -->
  <div class="form-group">
    <label for="phone">
      Phone Number
      <span class="required" aria-label="required">*</span>
    </label>
    <p id="phone-instructions">Enter 10-digit U.S. phone number (format: 555-123-4567)</p>
    <input
      type="tel"
      id="phone"
      name="phone"
      aria-describedby="phone-instructions"
      pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
      placeholder="555-123-4567"
    />
  </div>

  <!-- 3.3.7: Redundant entry prevention -->
  <fieldset>
    <legend>Billing Address</legend>
    <label>
      <input type="checkbox" id="same-as-shipping" checked />
      Same as shipping address
    </label>
    <div id="billing-fields" style="display:none;">
      <!-- Billing fields only shown if checkbox unchecked -->
    </div>
  </fieldset>

  <!-- 3.3.4: Error prevention for financial transaction -->
  <button type="submit">Review Order</button>
</form>

<!-- Confirmation page before finalizing -->
<div class="order-review">
  <h2>Review Your Order</h2>
  <p>Please confirm your order details before submitting payment.</p>

  <dl>
    <dt>Total:</dt>
    <dd>$299.99</dd>

    <dt>Shipping Address:</dt>
    <dd>123 Main St, City, ST 12345</dd>
  </dl>

  <button onclick="history.back()">Edit Order</button>
  <button onclick="submitOrder()">Confirm and Pay</button>
</div>

<!-- 3.3.8: Accessible authentication -->
<form>
  <fieldset>
    <legend>Log In</legend>

    <label for="username">Username or Email</label>
    <input
      type="text"
      id="username"
      name="username"
      autocomplete="username"
    />

    <label for="password">Password</label>
    <input
      type="password"
      id="password"
      name="password"
      autocomplete="current-password"
    />
    <p>Your browser can save this password for you.</p>

    <button type="submit">Log In</button>
  </fieldset>

  <p>
    <a href="/reset-password">Forgot password?</a>
    (We'll email you a reset link - no cognitive test required)
  </p>
</form>

Principle 4: Robust

4.1 Compatible

4.1.1 Parsing (Level A) - OBSOLETE in WCAG 2.2

  • Removed in WCAG 2.2 (HTML5 parsing is now standardized)

4.1.2 Name, Role, Value (Level A)

  • All UI components have accessible name
  • Component roles communicated to assistive tech
  • States (checked, expanded) programmatically available
  • Changes announced to screen readers

4.1.3 Status Messages (Level AA)

  • Status updates announced without focus change
  • Use ARIA live regions for dynamic content
  • Loading states communicated
  • Success/error messages announced

Implementation:

<!-- 4.1.2: Name, role, value -->
<!-- Custom checkbox -->
<div
  role="checkbox"
  aria-checked="false"
  aria-labelledby="terms-label"
  tabindex="0"
  onclick="toggleCheckbox(this)"
  onkeydown="if(event.key === ' ') { toggleCheckbox(this); event.preventDefault(); }"
>
  <span id="terms-label">I agree to the terms and conditions</span>
</div>

<script>
function toggleCheckbox(el) {
  const isChecked = el.getAttribute('aria-checked') === 'true';
  el.setAttribute('aria-checked', !isChecked);
  el.classList.toggle('checked');
}
</script>

<!-- Expandable section -->
<button
  aria-expanded="false"
  aria-controls="details-panel"
  onclick="togglePanel()"
>
  Show Details
</button>

<div id="details-panel" hidden>
  <p>Additional information...</p>
</div>

<script>
function togglePanel() {
  const button = event.target;
  const panel = document.getElementById('details-panel');
  const isExpanded = button.getAttribute('aria-expanded') === 'true';

  button.setAttribute('aria-expanded', !isExpanded);
  panel.hidden = isExpanded;
  button.textContent = isExpanded ? 'Show Details' : 'Hide Details';
}
</script>

<!-- 4.1.3: Status messages -->
<!-- Live region for search results -->
<div role="status" aria-live="polite" aria-atomic="true" class="sr-only">
  <span id="search-status"></span>
</div>

<input
  type="search"
  aria-label="Search products"
  oninput="performSearch(this.value)"
/>

<div id="results"></div>

<script>
function performSearch(query) {
  fetch(`/api/search?q=${query}`)
    .then(res => res.json())
    .then(data => {
      document.getElementById('results').innerHTML = renderResults(data);

      // Announce result count to screen readers
      const status = document.getElementById('search-status');
      status.textContent = `${data.length} results found for "${query}"`;
    });
}
</script>

<!-- Form submission status -->
<form onsubmit="handleSubmit(event)">
  <div role="alert" aria-live="assertive" id="form-status" class="sr-only"></div>

  <!-- form fields -->

  <button type="submit">Submit</button>
</form>

<script>
function handleSubmit(e) {
  e.preventDefault();
  const status = document.getElementById('form-status');

  // Show loading state
  status.textContent = 'Submitting form, please wait...';

  fetch('/api/submit', { method: 'POST', body: new FormData(e.target) })
    .then(res => res.json())
    .then(data => {
      if (data.success) {
        status.textContent = 'Form submitted successfully!';
      } else {
        status.textContent = `Error: ${data.message}`;
      }
    })
    .catch(err => {
      status.textContent = 'An error occurred. Please try again.';
    });
}
</script>

<style>
/* Screen reader only class */
.sr-only {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
</style>

Prioritized Implementation Roadmap

Phase 1: Critical Compliance (Weeks 1-2)

Goal: Achieve basic WCAG 2.2 Level A compliance and eliminate highest-risk violations.

Priority 1 Tasks:

  1. Keyboard Accessibility (2.1.1, 2.1.2)

    • Test all functionality with keyboard only (no mouse)
    • Add keyboard handlers to custom widgets
    • Fix keyboard traps in modals/menus
    • Estimated effort: 8-16 hours
    • Impact: HIGH - Affects all keyboard users
  2. Alt Text (1.1.1)

    • Audit all images for alt text
    • Add descriptive alt text to informative images
    • Use empty alt for decorative images
    • Estimated effort: 4-12 hours (depending on image count)
    • Impact: HIGH - Affects all screen reader users
  3. Form Labels (1.3.1, 3.3.2)

    • Associate all inputs with <label> elements
    • Add instructions for complex inputs
    • Mark required fields programmatically
    • Estimated effort: 4-8 hours
    • Impact: HIGH - Affects form completion rates
  4. Color Contrast (1.4.3)

    • Run automated contrast checker (WebAIM, axe)
    • Fix text with <4.5:1 contrast
    • Fix UI components with <3:1 contrast
    • Estimated effort: 8-20 hours
    • Impact: HIGH - Affects low vision users
  5. Page Titles (2.4.2)

    • Audit all pages for descriptive titles
    • Use format: "Page Name - Site Name"
    • Ensure titles describe page purpose
    • Estimated effort: 2-4 hours
    • Impact: MEDIUM - Navigation aid

Phase 1 Testing:

  • Manual keyboard navigation test
  • Screen reader test (NVDA or JAWS)
  • Automated scan with axe DevTools
  • Color contrast checker

Phase 2: Full Level AA Compliance (Weeks 3-6)

Goal: Achieve complete WCAG 2.2 Level AA compliance.

Priority 2 Tasks:

  1. WCAG 2.2 New Criteria

    • Implement 2.4.11 Focus Not Obscured (scroll-padding)
    • Implement 2.5.7 Dragging alternatives (keyboard/click)
    • Implement 2.5.8 Target Size Minimum (24×24px)
    • Implement 3.2.6 Consistent Help (same location)
    • Implement 3.3.7 Redundant Entry (autocomplete)
    • Implement 3.3.8 Accessible Authentication (password managers)
    • Estimated effort: 12-24 hours
    • Impact: HIGH - New compliance requirements
  2. Semantic HTML Structure (1.3.1)

    • Use proper heading hierarchy (h1 → h2 → h3)
    • Mark up lists with <ul>/<ol>
    • Use <table> for data tables with proper headers
    • Add ARIA landmarks (main, nav, aside, footer)
    • Estimated effort: 8-16 hours
    • Impact: HIGH - Screen reader navigation
  3. Focus Indicators (2.4.7, 2.4.11)

    • Ensure all interactive elements have visible focus
    • Use 3:1 contrast for focus indicators
    • Add scroll-padding to prevent sticky header obscuring
    • Estimated effort: 4-8 hours
    • Impact: HIGH - Keyboard user visibility
  4. Responsive Reflow (1.4.10)

    • Test at 320px width (mobile)
    • Eliminate horizontal scrolling
    • Test at 400% zoom
    • Estimated effort: 8-16 hours
    • Impact: MEDIUM - Mobile and zoom users
  5. ARIA Live Regions (4.1.3)

    • Add status announcements for dynamic content
    • Implement loading states
    • Announce form submission results
    • Estimated effort: 6-12 hours
    • Impact: MEDIUM - Screen reader UX

Phase 2 Testing:

  • Comprehensive screen reader test
  • Mobile responsiveness test
  • Zoom test (200%, 400%)
  • Full manual audit against checklist

Phase 3: Ongoing Maintenance (Continuous)

Goal: Maintain compliance and prevent regression.

Ongoing Tasks:

  1. Automated Testing Integration

    • Add axe-core to CI/CD pipeline
    • Set up Lighthouse CI for accessibility scoring
    • Configure Pa11y for regression testing
    • Estimated effort: 8-16 hours initial setup
    • Impact: HIGH - Prevents regression
  2. Manual Testing Schedule

    • Monthly screen reader testing
    • Quarterly comprehensive audit
    • Test new features before launch
    • Estimated effort: 4-8 hours/month
    • Impact: HIGH - Continuous compliance
  3. Team Training

    • Accessibility training for developers
    • Content editor training for alt text
    • Design team training for color/contrast
    • Estimated effort: 8-16 hours initial
    • Impact: HIGH - Organizational capability
  4. Documentation

    • Create accessibility statement
    • Document conformance level
    • Provide feedback mechanism
    • Estimated effort: 4-8 hours
    • Impact: MEDIUM - Transparency and legal protection

Testing and Validation

Automated Testing Tools

Browser Extensions:

  1. axe DevTools (Free/Pro)

  2. WAVE (WebAIM)

  3. Lighthouse (Chrome DevTools)

    • Built into Chrome (F12 → Lighthouse tab)
    • Accessibility score 0-100
    • Performance + SEO audits included
    • Run: Chrome DevTools → Lighthouse → Accessibility

Command Line Tools: 4. Pa11y

npm install -g pa11y
pa11y https://your-website.com
  • CI/CD integration
  • Test multiple pages
  • JSON/HTML reports
  1. axe-core CLI
    npm install -g @axe-core/cli
    axe https://your-website.com
    
    • Same engine as axe DevTools
    • Scriptable testing
    • CI/CD integration

Manual Testing Protocol

1. Keyboard Navigation Test (15-30 minutes)

  • Disconnect mouse
  • Tab through entire page
  • Verify all interactive elements reachable
  • Check focus indicators visible
  • Test Esc/Enter/Space/Arrow keys in widgets
  • Ensure no keyboard traps

2. Screen Reader Test (30-60 minutes)

Windows + NVDA (Free):

Download NVDA: https://www.nvaccess.org/download/
1. Install NVDA
2. Launch NVDA (Ctrl+Alt+N)
3. Navigate page with:
   - H: Next heading
   - 1-6: Jump to heading level
   - K: Next link
   - F: Next form field
   - T: Next table
   - L: Next list
   - Insert+F7: Elements list
4. Verify all content announced correctly
5. Test forms with Tab/Arrow keys

Mac + VoiceOver (Built-in):

1. Enable VoiceOver: Cmd+F5
2. Navigate with:
   - VO+Right/Left Arrow: Next/previous item
   - VO+H: Next heading
   - VO+U: Rotor menu (headings, links, forms)
   - VO+Space: Activate element
3. Test all interactive elements
4. Verify announcements clear and accurate

3. Mobile Testing (30-45 minutes)

  • Test on iOS Safari with VoiceOver (Settings → Accessibility → VoiceOver)
  • Test on Android Chrome with TalkBack (Settings → Accessibility → TalkBack)
  • Verify touch target sizes (24×24px minimum)
  • Test pinch-to-zoom not disabled
  • Check orientation support (portrait/landscape)

4. Zoom/Magnification Test (15-20 minutes)

  • Zoom to 200% (Ctrl/Cmd +)
  • Verify no content loss
  • Verify no horizontal scrolling
  • Zoom to 400%
  • Check text spacing (line-height, letter-spacing)

5. Color/Contrast Test (10-15 minutes)

  • Use WebAIM Contrast Checker: https://webaim.org/resources/contrastchecker/
  • Test all text colors against backgrounds
  • Test button/link colors
  • Test focus indicators
  • Use browser's "Simulate color blindness" (Chrome DevTools → Rendering)

Common Compliance Gaps

Top 10 WCAG Violations (Based on WebAIM Million 2024)

  1. Low Color Contrast (83.6% of sites)

    • Issue: Text with <4.5:1 contrast ratio
    • Fix: Use WebAIM Contrast Checker, darken text or lighten background
    • Example: Light gray (#999) on white fails - use #595959 or darker
  2. Missing Alt Text (54.5% of sites)

    • Issue: <img> without alt attribute
    • Fix: Add descriptive alt text or empty alt for decorative
    • Example: <img src="logo.png" alt="AllAccessible homepage">
  3. Empty Links (44.6% of sites)

    • Issue: <a> with no text content
    • Fix: Add descriptive text or aria-label
    • Example: <a href="/search" aria-label="Search site"><svg>...</svg></a>
  4. Missing Form Labels (45.9% of sites)

    • Issue: <input> without associated <label>
    • Fix: Wrap input in label or use for/id association
    • Example: <label for="email">Email</label><input id="email" />
  5. Empty Buttons (25.4% of sites)

    • Issue: <button> with no text
    • Fix: Add text or aria-label
    • Example: <button aria-label="Close dialog"><svg>X</svg></button>
  6. Missing Document Language (17.1% of sites)

    • Issue: <html> without lang attribute
    • Fix: Add lang="en" (or appropriate language code)
    • Example: <html lang="en">
  7. Improper Heading Order (38.2% of sites)

    • Issue: Skipping heading levels (h1 → h3)
    • Fix: Use hierarchical structure (h1 → h2 → h3)
    • Example: Don't skip from <h1> to <h3> - use <h2>
  8. Insufficient Focus Indicators (NEW WCAG 2.2 emphasis)

    • Issue: :focus { outline: none } without replacement
    • Fix: Always provide visible 3:1 contrast focus indicator
    • Example: :focus { outline: 3px solid #0066CC }
  9. Small Touch Targets (NEW WCAG 2.2)

    • Issue: Buttons smaller than 24×24 CSS pixels
    • Fix: Use min-width/min-height of 24px minimum
    • Example: .icon-btn { min-width: 24px; min-height: 24px; }
  10. Drag-Only Interactions (NEW WCAG 2.2)

    • Issue: Functionality only available via dragging
    • Fix: Provide keyboard/click alternative
    • Example: Add up/down buttons to sortable list

Legal and Regulatory Context

U.S. Regulations

ADA Title III (Americans with Disabilities Act)

  • Applies to: Public accommodations (businesses, nonprofits)
  • Standard: Courts increasingly reference WCAG 2.1 Level AA
  • Lawsuits: 4,605 federal lawsuits filed in 2023 (UsableNet)
  • Trend: Shifting to WCAG 2.2 as new standard
  • Penalties: $75,000-$150,000 plus plaintiff attorney fees

Section 508 (Rehabilitation Act)

  • Applies to: Federal agencies and contractors
  • Standard: WCAG 2.0 Level AA (updating to 2.2)
  • Enforcement: Access Board, DOJ
  • Impact: Government RFPs require 508 compliance

European Union

European Accessibility Act (EAA)

  • Enforcement Date: June 28, 2025 (now in force)
  • Applies to: E-commerce, banking, transport, e-books, communication services
  • Standard: EN 301 549 (harmonized with WCAG 2.1 AA)
  • Penalties: Varies by country, up to 4% of annual turnover
  • Scope: B2C and B2B services in EU

Web Accessibility Directive (WAD)

  • Applies to: Public sector websites/apps
  • Standard: WCAG 2.1 Level AA
  • Monitoring: National enforcement bodies conduct audits
  • Reporting: Accessibility statements required

Other Jurisdictions

United Kingdom

  • Equality Act 2010: Requires reasonable adjustments for disabled users
  • Public Sector Bodies Regulation 2018: WCAG 2.1 AA for government

Canada

  • Accessible Canada Act (ACA): Phased WCAG 2.1 AA compliance
  • AODA (Ontario): WCAG 2.0 Level AA by 2021 (updating to 2.1)

Australia

  • Disability Discrimination Act 1992: WCAG 2.1 Level AA recommended
  • Government: AS EN 301 549 required for federal agencies

Downloadable Resources

Free WCAG 2.2 Tools

Checklists:

  1. WCAG 2.2 AA Compliance Spreadsheet

    • All 86 success criteria
    • Pass/Fail tracking
    • Priority levels
    • Download: [Create your own using this guide]
  2. WebAIM WCAG 2 Checklist

Testing Tools: 3. Accessibility Insights for Web (Microsoft)

  1. Color Contrast Analyzer (TPGi)

Code Libraries: 5. ARIA Authoring Practices Guide


Implementation Priorities by Industry

E-commerce

Critical:

  • Product images with descriptive alt text (1.1.1)
  • Keyboard-accessible checkout (2.1.1)
  • Form labels and error messages (3.3.1, 3.3.3)
  • Redundant entry prevention for shipping/billing (3.3.7) ⭐ NEW
  • Accessible authentication (3.3.8) ⭐ NEW

High Priority:

  • Color contrast for CTAs (1.4.3)
  • Target size for mobile checkout (2.5.8) ⭐ NEW
  • Focus visibility in product filters (2.4.7)

SaaS/Web Apps

Critical:

  • Keyboard navigation for all features (2.1.1, 2.1.2)
  • ARIA for custom widgets (4.1.2)
  • Focus management in modals (2.4.3)
  • Status messages for async operations (4.1.3)

High Priority:

  • Dragging alternatives for drag-drop UI (2.5.7) ⭐ NEW
  • Session timeout warnings (2.2.1)
  • Consistent help across pages (3.2.6) ⭐ NEW

Content/Publishing

Critical:

  • Alt text for editorial images (1.1.1)
  • Heading structure (1.3.1)
  • Captions for video content (1.2.2)
  • Language declaration (3.1.1, 3.1.2)

High Priority:

  • Color contrast for body text (1.4.3)
  • Responsive reflow (1.4.10)
  • Multiple navigation methods (2.4.5)

Government/Public Sector

Critical:

  • Full WCAG 2.2 Level AA compliance (all criteria)
  • Accessible forms for public services (3.3.1-3.3.4)
  • Captions and transcripts (1.2.2, 1.2.4)
  • VPAT documentation

High Priority:

  • Accessible authentication for citizen portals (3.3.8) ⭐ NEW
  • Consistent help mechanisms (3.2.6) ⭐ NEW
  • Print-friendly formats

Next Steps

Week 1 Action Items

  1. Run Automated Scan

    • Install axe DevTools browser extension
    • Scan homepage and 5 key pages
    • Export results to spreadsheet
  2. Keyboard Test

    • Navigate entire site with Tab/Shift+Tab
    • Document keyboard traps or unreachable elements
    • Note missing focus indicators
  3. Review Forms

    • Audit all forms for labels
    • Check error messages
    • Test form submission
  4. Contrast Audit

    • Run WebAIM Contrast Checker on text elements
    • Document failing combinations
    • Prioritize high-traffic pages

Month 1 Goals

  • Fix all critical Level A violations
  • Achieve 80%+ automated testing pass rate
  • Complete keyboard accessibility for main user flows
  • Implement new WCAG 2.2 criteria (Focus Not Obscured, Target Size)

Quarter 1 Goals

  • Full WCAG 2.2 Level AA compliance
  • Manual testing with screen readers
  • Accessibility statement published
  • Team training completed
  • Automated testing in CI/CD

Get Expert Help

AllAccessible Platform:

  • Automated WCAG 2.2 scanning
  • JavaScript widget for instant improvements
  • Manual audit services
  • Remediation support
  • Start free trial: https://allaccessible.org

Need a Custom Audit? AllAccessible provides:

  • Comprehensive WCAG 2.2 AA audits
  • Remediation roadmaps with effort estimates
  • Developer training and support
  • Ongoing monitoring and maintenance
  • Contact us: https://allaccessible.org/contact

Frequently Asked Questions

Q: Do I need WCAG 2.2 or is 2.1 enough? A: While WCAG 2.1 Level AA is currently the legal standard in most jurisdictions, WCAG 2.2 is backward-compatible and adds important improvements. With the EU's EAA now in force since June 2025 and increasing adoption worldwide, targeting WCAG 2.2 AA ensures current and future compliance.

Q: How long does it take to become WCAG 2.2 compliant? A: For an existing site with moderate accessibility issues, expect:

  • Simple brochure site: 2-4 weeks
  • Complex e-commerce site: 2-4 months
  • Large web application: 4-6 months

Time depends on current state, team size, and complexity.

Q: Can I use an overlay widget to become compliant? A: No. Overlay widgets (like AccessiBe, AudioEye, UserWay) do NOT provide legal compliance and have been cited in ADA lawsuits. True compliance requires fixing the underlying code.

Q: What's the ROI of accessibility? A: Studies show:

  • Market expansion: 26% of U.S. adults have disabilities (CDC)
  • SEO benefit: 40-50% overlap between accessibility and SEO best practices
  • Legal risk reduction: Average ADA lawsuit settlement: $50,000-$150,000
  • Conversion improvement: Accessible sites see 20-30% higher conversion rates

Q: Is Level AAA required? A: No. WCAG 2.2 Level AA is the recommended standard for legal compliance. Level AAA is optional and often not fully achievable for all content.

Q: How often should I test for accessibility? A: Recommended schedule:

  • Automated: Every code commit (CI/CD)
  • Manual keyboard test: Every sprint/release
  • Screen reader test: Monthly for key pages
  • Comprehensive audit: Quarterly

Q: What if I can't afford a full audit? A: Start with:

  1. Free automated tools (axe DevTools, WAVE)
  2. Manual keyboard testing (free)
  3. Fix critical issues first (keyboard, alt text, labels)
  4. Use AllAccessible's free tier for ongoing monitoring

Conclusion

WCAG 2.2 compliance is no longer optional—it's a legal requirement, business imperative, and ethical obligation. With the European Accessibility Act now in force since June 28, 2025, and ongoing ADA litigation in the U.S., organizations must prioritize accessibility immediately.

This comprehensive checklist provides everything you need to achieve and maintain WCAG 2.2 Level AA compliance:

  • ✅ Complete checklist of all 86 success criteria
  • ✅ Prioritized implementation roadmap
  • ✅ Real-world code examples
  • ✅ Testing protocols and tools
  • ✅ Legal context and deadlines

Start your compliance journey today with automated testing, keyboard navigation checks, and gradual remediation. The investment in accessibility pays dividends through expanded market reach, reduced legal risk, improved SEO, and better user experience for everyone.

Ready to achieve WCAG 2.2 compliance? Start your free AllAccessible trial for automated scanning, expert guidance, and ongoing monitoring.


About AllAccessible

AllAccessible provides comprehensive web accessibility solutions including automated WCAG 2.2 scanning, expert manual audits, remediation support, and ongoing compliance monitoring. Our platform helps businesses of all sizes achieve and maintain accessibility compliance while improving user experience for everyone.

Resources:

Share this article