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)
| Criterion |
Name |
Requirement |
| 2.4.11 |
Focus Not Obscured |
Focus never completely hidden |
| 2.5.7 |
Dragging Movements |
Alternative to drag operations |
| 2.5.8 |
Target Size (Minimum) |
24x24px minimum touch targets |
| 3.2.6 |
Consistent Help |
Help in same relative location |
| 3.3.7 |
Redundant Entry |
Don't re-ask for same info |
| 3.3.8 |
Accessible Authentication |
No 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
| Code |
Description |
WCAG |
Recovery |
A11Y001 |
Missing alt text |
1.1.1 |
Add descriptive alt |
A11Y002 |
Low color contrast |
1.4.3 |
Adjust colors to 4.5:1 |
A11Y003 |
Missing form label |
1.3.1 |
Add <label> or aria-label |
A11Y004 |
No keyboard access |
2.1.1 |
Add tabindex, handlers |
A11Y005 |
Missing skip link |
2.4.1 |
Add skip to main content |
A11Y006 |
Empty link/button |
2.4.4 |
Add accessible text |
A11Y007 |
Missing page title |
2.4.2 |
Add descriptive <title> |
A11Y008 |
Missing lang attr |
3.1.1 |
Add lang to <html> |
A11Y009 |
Focus not visible |
2.4.7 |
Add focus styles |
A11Y010 |
Target too small |
2.5.8 |
Increase to 24x24px |
Impact Levels
| Impact |
Description |
Examples |
| Critical |
Blocks access completely |
No keyboard, missing alt |
| Serious |
Major barrier |
Low contrast, no labels |
| Moderate |
Significant difficulty |
Missing skip link |
| Minor |
Inconvenience |
Suboptimal 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
| Component |
Keys |
Action |
| Buttons |
Enter, Space |
Activate |
| Links |
Enter |
Navigate |
| Checkboxes |
Space |
Toggle |
| Radio buttons |
Arrow keys |
Move selection |
| Tabs |
Arrow keys |
Switch tabs |
| Menus |
Arrow, Enter, Esc |
Navigate, select, close |
| Dialogs |
Esc, Tab |
Close, move focus |
| Listbox |
Arrow, Enter |
Navigate, select |
π Audit Scoring
| Category |
Weight |
Checks |
| Perceivable |
25% |
Alt text, contrast, captions |
| Operable |
30% |
Keyboard, focus, timing |
| Understandable |
25% |
Labels, errors, consistency |
| Robust |
20% |
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