Status: Production Ready ✅ Last Updated: 2026-01-14 Dependencies: None (framework-agnostic) Standards: WCAG 2.1 Level AA
Quick Start (5 Minutes)
1. Semantic HTML Foundation
Choose the right element - don't use div for everything:
CODEBLOCK0
Why this matters:
- Semantic elements have built-in keyboard support
Screen readers announce role automatically
Browser provides default accessible behaviors
2. Focus Management
Make interactive elements keyboard-accessible:
CODEBLOCK1
CRITICAL:
- Never remove focus outlines without replacement
Use :focus-visible to show only on keyboard focus
Ensure 3:1 contrast ratio for focus indicators
3. Text Alternatives
Every non-text element needs a text alternative:
CODEBLOCK2
The 5-Step Accessibility Process
Step 1: Choose Semantic HTML
Decision tree for element selection:
CODEBLOCK3
See references/semantic-html.md for complete guide.
Step 2: Add ARIA When Needed
Golden rule: Use ARIA only when HTML can't express the pattern.
CODEBLOCK4
Common ARIA patterns:
- aria-label - When visible label doesn't exist
INLINECODE4 - Reference existing text as label
INLINECODE5 - Additional description
INLINECODE6 - Announce dynamic updates
INLINECODE7 - Collapsible/expandable state
See references/aria-patterns.md for complete patterns.
Step 3: Implement Keyboard Navigation
All interactive elements must be keyboard-accessible:
CODEBLOCK5
Essential keyboard patterns:
- Tab/Shift+Tab: Navigate between focusable elements
Enter/Space: Activate buttons/links
Arrow keys: Navigate within components (tabs, menus)
Escape: Close dialogs/menus
Home/End: Jump to first/last item
See references/focus-management.md for complete patterns.
Step 4: Ensure Color Contrast
WCAG AA requirements:
- Normal text (under 18pt): 4.5:1 contrast ratio
Large text (18pt+ or 14pt+ bold): 3:1 contrast ratio
UI components (buttons, borders): 3:1 contrast ratio
CODEBLOCK6
Testing tools:
- Browser DevTools (Chrome/Firefox have built-in checkers)
Contrast checker extensions
axe DevTools extension
See references/color-contrast.md for complete guide.
Step 5: Make Forms Accessible
Every form input needs a visible label:
CODEBLOCK7
Error handling:
CODEBLOCK8
Live regions for dynamic errors:
CODEBLOCK9
See references/forms-validation.md for complete patterns.
Critical Rules
Always Do
✅ Use semantic HTML elements first (button, a, nav, article, etc.)
✅ Provide text alternatives for all non-text content
✅ Ensure 4.5:1 contrast for normal text, 3:1 for large text/UI
✅ Make all functionality keyboard accessible
✅ Test with keyboard only (unplug mouse)
✅ Test with screen reader (NVDA on Windows, VoiceOver on Mac)
✅ Use proper heading hierarchy (h1 → h2 → h3, no skipping)
✅ Label all form inputs with visible labels
✅ Provide focus indicators (never just outline: none)
✅ Use aria-live for dynamic content updates
Never Do
❌ Use div with onClick instead of button
❌ Remove focus outlines without replacement
❌ Use color alone to convey information
❌ Use placeholders as labels
❌ Skip heading levels (h1 → h3)
❌ Use tabindex > 0 (messes with natural order)
❌ Add ARIA when semantic HTML exists
❌ Forget to restore focus after closing dialogs
❌ Use role="presentation" on focusable elements
❌ Create keyboard traps (no way to escape)
Known Issues Prevention
This skill prevents 12 documented accessibility issues:
Issue #1: Missing Focus Indicators
Error: Interactive elements have no visible focus indicator Source: WCAG 2.4.7 (Focus Visible) Why It Happens: CSS reset removes default outline Prevention: Always provide custom focus-visible styles
Issue #2: Insufficient Color Contrast
Error: Text has less than 4.5:1 contrast ratio Source: WCAG 1.4.3 (Contrast Minimum) Why It Happens: Using light gray text on white background Prevention: Test all text colors with contrast checker
Issue #3: Missing Alt Text
Error: Images missing alt attributes Source: WCAG 1.1.1 (Non-text Content) Why It Happens: Forgot to add or thought it was optional Prevention: Add alt="" for decorative, descriptive alt for meaningful images
Issue #4: Keyboard Navigation Broken
Error: Interactive elements not reachable by keyboard Source: WCAG 2.1.1 (Keyboard) Why It Happens: Using div onClick instead of button Prevention: Use semantic interactive elements (button, a)
Issue #5: Form Inputs Without Labels
Error: Input fields missing associated labels Source: WCAG 3.3.2 (Labels or Instructions) Why It Happens: Using placeholder as label Prevention: Always use <label> element with for/id association
Issue #6: Skipped Heading Levels
Error: Heading hierarchy jumps from h1 to h3 Source: WCAG 1.3.1 (Info and Relationships) Why It Happens: Using headings for visual styling instead of semantics Prevention: Use headings in order, style with CSS
Issue #7: No Focus Trap in Dialogs
Error: Tab key exits dialog to background content Source: WCAG 2.4.3 (Focus Order) Why It Happens: No focus trap implementation Prevention: Implement focus trap for modal dialogs
Issue #8: Missing aria-live for Dynamic Content
Error: Screen reader doesn't announce updates Source: WCAG 4.1.3 (Status Messages) Why It Happens: Dynamic content added without announcement Prevention: Use aria-live="polite" or "assertive"
Issue #9: Color-Only Information
Error: Using only color to convey status Source: WCAG 1.4.1 (Use of Color) Why It Happens: Red text for errors without icon/text Prevention: Add icon + text label, not just color
Issue #10: Non-descriptive Link Text
Error: Links with "click here" or "read more" Source: WCAG 2.4.4 (Link Purpose) Why It Happens: Generic link text without context Prevention: Use descriptive link text or aria-label
Issue #11: Auto-playing Media
Error: Video/audio auto-plays without user control Source: WCAG 1.4.2 (Audio Control) Why It Happens: Autoplay attribute without controls Prevention: Require user interaction to start media
Issue #12: Inaccessible Custom Controls
Error: Custom select/checkbox without keyboard support Source: WCAG 4.1.2 (Name, Role, Value) Why It Happens: Building from divs without ARIA Prevention: Use native elements or implement full ARIA pattern
WCAG 2.1 AA Quick Checklist
Perceivable
- [ ] All images have alt text (or alt="" if decorative)
[ ] Text contrast ≥ 4.5:1 (normal), ≥ 3:1 (large)
[ ] Color not used alone to convey information
[ ] Text can be resized to 200% without loss of content
[ ] No auto-playing audio >3 seconds
Operable
- [ ] All functionality keyboard accessible
[ ] No keyboard traps
[ ] Visible focus indicators
[ ] Users can pause/stop/hide moving content
[ ] Page titles describe purpose
[ ] Focus order is logical
[ ] Link purpose clear from text or context
[ ] Multiple ways to find pages (menu, search, sitemap)
[ ] Headings and labels describe purpose
Understandable
- [ ] Page language specified (<html lang="en">)
[ ] Language changes marked (<span lang="es">)
[ ] No unexpected context changes on focus/input
[ ] Consistent navigation across site
[ ] Form labels/instructions provided
[ ] Input errors identified and described
[ ] Error prevention for legal/financial/data changes
Robust
- [ ] Valid HTML (no parsing errors)
[ ] Name, role, value available for all UI components
Symptoms: Can tab through page but don't see where focus is Cause: CSS removed outlines or insufficient contrast Solution:
CODEBLOCK18
Problem: Screen reader not announcing updates
Symptoms: Dynamic content changes but no announcement Cause: No aria-live region Solution: Wrap dynamic content in <div aria-live="polite"> or use role="alert"
Problem: Dialog focus escapes to background
Symptoms: Tab key navigates to elements behind dialog Cause: No focus trap Solution: Implement focus trap (see Pattern 1 above)
Problem: Form errors not announced
Symptoms: Visual errors appear but screen reader doesn't notice Cause: No aria-invalid or role="alert" Solution: Use aria-invalid + aria-describedby pointing to error message with role="alert"
Complete Setup Checklist
Use this for every page/component:
- [ ] All interactive elements are keyboard accessible
[ ] Visible focus indicators on all focusable elements
[ ] Images have alt text (or alt="" if decorative)
[ ] Text contrast ≥ 4.5:1 (test with axe or Lighthouse)
[ ] Form inputs have associated labels (not just placeholders)
[ ] Heading hierarchy is logical (no skipped levels)
[ ] Page has <html lang="en"> or appropriate language
[ ] Dialogs have focus trap and restore focus on close
[ ] Dynamic content uses aria-live or role="alert"
[ ] Color not used alone to convey information
[ ] Tested with keyboard only (no mouse)
[ ] Tested with screen reader (NVDA or VoiceOver)
[ ] Ran axe DevTools scan (0 violations)
[ ] Lighthouse accessibility score ≥ 90
Questions? Issues?
1. Check references/wcag-checklist.md for complete requirements
- Initial release of the accessibility skill, designed for building WCAG 2.1 AA compliant websites.
- Provides clear guidance on semantic HTML, ARIA usage, focus management, screen reader support, color contrast, keyboard navigation, accessible forms, and live regions.
- Includes "always do" and "never do" checklists to prevent common accessibility mistakes.
- Lists 12 documented accessibility issues this skill helps prevent, with references for deeper learning.