pluginagentmarketplace avatar

accessibility

WCAG 2.2 AA compliance, ARIA patterns, screen reader compatibility, and inclusive design patterns

by pluginagentmarketplace|Open Source

Accessibility Skill

WCAG 2.2 compliance and ARIA implementation for inclusive, accessible web experiences.

🎯 Purpose

Provide atomic, single-responsibility operations for:

  • WCAG 2.2 Level A/AA/AAA auditing
  • ARIA roles, states, and properties
  • Keyboard navigation patterns
  • Screen reader optimization
  • Focus management
  • Color contrast verification

πŸ“₯ Input Schema

interface AccessibilityInput {
  operation: 'audit' | 'fix' | 'pattern' | 'explain';
  audit_level: 'A' | 'AA' | 'AAA';
  markup?: string;
  component_type?: ComponentType;
  context?: {
    user_agents: string[];     // Target screen readers
    focus_management: boolean;
    color_scheme: 'light' | 'dark' | 'both';
  };
}

type ComponentType =
  | 'interactive'   // Buttons, links, controls
  | 'form'          // Form elements
  | 'navigation'    // Menus, breadcrumbs
  | 'media'         // Images, video, audio
  | 'content'       // Text, headings, lists
  | 'widget';       // Custom components

πŸ“€ Output Schema

interface AccessibilityOutput {
  success: boolean;
  wcag_level: 'A' | 'AA' | 'AAA';
  score: number;              // 0-100
  issues: A11yIssue[];
  fixes: A11yFix[];
  passed_criteria: string[];
  failed_criteria: string[];
}

interface A11yIssue {
  criterion: string;          // e.g., "1.4.3"
  level: 'A' | 'AA' | 'AAA';
  impact: 'critical' | 'serious' | 'moderate' | 'minor';
  element: string;
  message: string;
  fix: string;
}

πŸ› οΈ WCAG 2.2 Quick Reference

The Four Principles (POUR)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        WCAG POUR                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   PERCEIVABLE  β”‚   OPERABLE     β”‚ UNDERSTANDABLE β”‚  ROBUST  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Text alt       β”‚ Keyboard       β”‚ Readable       β”‚ Compatibleβ”‚
β”‚ Captions       β”‚ Enough time    β”‚ Predictable    β”‚ Parsing  β”‚
β”‚ Adaptable      β”‚ Seizures       β”‚ Input assist   β”‚          β”‚
β”‚ Distinguishableβ”‚ Navigable      β”‚                β”‚          β”‚
β”‚                β”‚ Input modality β”‚                β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

WCAG 2.2 New Success Criteria (AA)

CriterionNameRequirement
2.4.11Focus Not ObscuredFocus never completely hidden
2.5.7Dragging MovementsAlternative to drag operations
2.5.8Target Size (Minimum)24x24px minimum touch targets
3.2.6Consistent HelpHelp in same relative location
3.3.7Redundant EntryDon't re-ask for same info
3.3.8Accessible AuthenticationNo cognitive tests for login

🎨 ARIA Patterns

1. Interactive Widgets

Button

<!-- Native button (preferred) -->
<button type="button">Click me</button>

<!-- Custom button (when native not possible) -->
<div role="button"
     tabindex="0"
     aria-pressed="false"
     onkeydown="handleKeydown(event)">
  Toggle
</div>

Dialog (Modal)

<div role="dialog"
     aria-modal="true"
     aria-labelledby="dialog-title"
     aria-describedby="dialog-desc">
  <h2 id="dialog-title">Confirm Action</h2>
  <p id="dialog-desc">Are you sure you want to proceed?</p>
  <button>Cancel</button>
  <button>Confirm</button>
</div>

Tabs

<div role="tablist" aria-label="Settings">
  <button role="tab"
          aria-selected="true"
          aria-controls="panel-1"
          id="tab-1">
    General
  </button>
  <button role="tab"
          aria-selected="false"
          aria-controls="panel-2"
          id="tab-2"
          tabindex="-1">
    Privacy
  </button>
</div>

<div role="tabpanel"
     id="panel-1"
     aria-labelledby="tab-1">
  General settings content...
</div>

<div role="tabpanel"
     id="panel-2"
     aria-labelledby="tab-2"
     hidden>
  Privacy settings content...
</div>

2. Live Regions

<!-- Polite announcement (waits for pause) -->
<div aria-live="polite" aria-atomic="true">
  3 items in cart
</div>

<!-- Assertive announcement (interrupts) -->
<div role="alert" aria-live="assertive">
  Error: Please fix the form errors
</div>

<!-- Status message -->
<div role="status" aria-live="polite">
  File uploaded successfully
</div>

3. Form Patterns

<form>
  <!-- Required field -->
  <label for="email">Email (required)</label>
  <input type="email"
         id="email"
         name="email"
         required
         aria-required="true"
         aria-describedby="email-hint email-error">
  <p id="email-hint">We'll never share your email</p>
  <p id="email-error" role="alert" aria-live="polite"></p>

  <!-- Field with error -->
  <label for="password">Password</label>
  <input type="password"
         id="password"
         aria-invalid="true"
         aria-errormessage="pwd-error">
  <p id="pwd-error" role="alert">
    Password must be at least 8 characters
  </p>

  <!-- Checkbox group -->
  <fieldset>
    <legend>Notifications</legend>
    <label>
      <input type="checkbox" name="notify" value="email">
      Email
    </label>
    <label>
      <input type="checkbox" name="notify" value="sms">
      SMS
    </label>
  </fieldset>
</form>

⚠️ Error Handling

Error Codes

CodeDescriptionWCAGRecovery
A11Y001Missing alt text1.1.1Add descriptive alt
A11Y002Low color contrast1.4.3Adjust colors to 4.5:1
A11Y003Missing form label1.3.1Add <label> or aria-label
A11Y004No keyboard access2.1.1Add tabindex, handlers
A11Y005Missing skip link2.4.1Add skip to main content
A11Y006Empty link/button2.4.4Add accessible text
A11Y007Missing page title2.4.2Add descriptive <title>
A11Y008Missing lang attr3.1.1Add lang to <html>
A11Y009Focus not visible2.4.7Add focus styles
A11Y010Target too small2.5.8Increase to 24x24px

Impact Levels

ImpactDescriptionExamples
CriticalBlocks access completelyNo keyboard, missing alt
SeriousMajor barrierLow contrast, no labels
ModerateSignificant difficultyMissing skip link
MinorInconvenienceSuboptimal reading order

πŸ” Troubleshooting

Problem: Screen reader not announcing content

Debug Checklist:
β–‘ Element has accessible name?
β–‘ ARIA role correct?
β–‘ aria-hidden not incorrectly set?
β–‘ Content not CSS display:none?
β–‘ Live region set up correctly?

Problem: Keyboard navigation broken

Debug Checklist:
β–‘ All interactive elements focusable?
β–‘ Tab order logical?
β–‘ No keyboard traps?
β–‘ Focus visible?
β–‘ Custom widgets have key handlers?
β–‘ Arrow key navigation for widgets?

Problem: Form not accessible

Debug Checklist:
β–‘ All inputs have labels?
β–‘ Required fields marked?
β–‘ Errors announced via live region?
β–‘ Error linked with aria-errormessage?
β–‘ Fieldsets for groups?
β–‘ Autocomplete attributes set?

Keyboard Navigation Patterns

ComponentKeysAction
ButtonsEnter, SpaceActivate
LinksEnterNavigate
CheckboxesSpaceToggle
Radio buttonsArrow keysMove selection
TabsArrow keysSwitch tabs
MenusArrow, Enter, EscNavigate, select, close
DialogsEsc, TabClose, move focus
ListboxArrow, EnterNavigate, select

πŸ“Š Audit Scoring

CategoryWeightChecks
Perceivable25%Alt text, contrast, captions
Operable30%Keyboard, focus, timing
Understandable25%Labels, errors, consistency
Robust20%Valid HTML, ARIA usage

Score Interpretation:

  • 90-100: Excellent (WCAG AA likely compliant)
  • 70-89: Good (some issues to address)
  • 50-69: Moderate (significant work needed)
  • <50: Poor (major accessibility barriers)

πŸ“‹ Usage Examples

# Audit markup for WCAG AA
skill: accessibility
operation: audit
audit_level: "AA"
markup: "<form>...</form>"

# Get accessible pattern
skill: accessibility
operation: pattern
component_type: widget
context:
  user_agents: ["NVDA", "VoiceOver"]

# Fix accessibility issues
skill: accessibility
operation: fix
audit_level: "AA"
markup: "<img src='photo.jpg'>"
output_format: both

πŸ”— References