accessibility
Audits web and mobile applications for accessibility compliance (WCAG 2.1). Checks keyboard navigation, screen reader support, color contrast, focus management, and semantic markup. Use when reviewing UI code, building new components, or preparing for accessibility audits.
Accessibility Audit
Accessibility isn't a feature - it's a quality bar. If it doesn't work with a keyboard, a screen reader, or low vision, it's broken.
Quick Checks (Do These First)
1. Keyboard Navigation
- Tab through the entire page - can you reach every interactive element?
- Tab order follows visual order (no jumping around)
- Focus indicator is visible on every focused element
- Escape closes modals/popups and returns focus to trigger
- Enter/Space activates buttons and links
- Arrow keys work in menus, tabs, and custom widgets
- No keyboard traps (can always Tab away from any element)
2. Screen Reader
- Every image has
alttext (oralt=""for decorative images) - Form inputs have associated
<label>elements - Buttons and links have descriptive text (not "Click here")
- Page has a single
<h1>, heading hierarchy doesn't skip levels - Dynamic content changes announced (ARIA live regions)
- Custom components have appropriate ARIA roles and states
3. Visual
- Text contrast ratio ≥ 4.5:1 (normal text) or ≥ 3:1 (large text)
- Information not conveyed by color alone (add icons, patterns, text)
- Text resizable to 200% without loss of content
- UI functional at 320px width (mobile) without horizontal scroll
- Animations respect
prefers-reduced-motion
Semantic HTML
Use the right element. It gets you keyboard and screen reader support for free.
| Need | Use | NOT |
|---|---|---|
| Navigation | <nav> | <div class="nav"> |
| Button | <button> | <div onClick> or <a href="#"> |
| Link (navigate) | <a href="..."> | <button> or <span onClick> |
| List | <ul>/<ol> | Divs with bullet characters |
| Heading | <h1>-<h6> | <div class="heading"> |
| Form field | <input> + <label> | <div contenteditable> |
| Table data | <table> + <th> | Divs in a grid layout |
| Main content | <main> | <div id="content"> |
Rule: If you're adding ARIA attributes to make a <div> behave like a button, you should just use a <button>.
ARIA Usage
ARIA is a last resort, not a first choice. Semantic HTML first.
When ARIA Is Needed
- Custom widgets with no HTML equivalent (tabs, combobox, tree view)
- Dynamic content updates (live regions)
- Relationships between elements that markup can't express
Common Patterns
<!-- Tabs -->
<div role="tablist">
<button role="tab" aria-selected="true" aria-controls="panel-1">Tab 1</button>
<button role="tab" aria-selected="false" aria-controls="panel-2">Tab 2</button>
</div>
<div role="tabpanel" id="panel-1">Content 1</div>
<!-- Modal -->
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
<h2 id="modal-title">Modal Title</h2>
<!-- Focus trapped inside modal -->
</div>
<!-- Live region (for dynamic updates) -->
<div aria-live="polite">
<!-- Screen reader announces changes here -->
3 items added to cart
</div>
<!-- Loading state -->
<button aria-busy="true" aria-disabled="true">
<span aria-hidden="true">⏳</span> Loading...
</button>
Focus Management
| Scenario | Focus Should Go To |
|---|---|
| Modal opens | First focusable element inside modal |
| Modal closes | Element that triggered the modal |
| Item deleted from list | Next item in list (or previous if last) |
| Page navigation (SPA) | Page heading or main content |
| Error on form submit | First field with an error |
| Accordion expands | The expanded content |
Color Contrast
| Element | Minimum Ratio | Check |
|---|---|---|
| Normal text (< 18px) | 4.5:1 | Required |
| Large text (≥ 18px bold or ≥ 24px) | 3:1 | Required |
| UI components (borders, icons) | 3:1 | Required |
| Decorative elements | No requirement | - |
Tools: Chrome DevTools (Inspect → color picker shows ratio), axe DevTools extension, WebAIM Contrast Checker.
Testing Tools
| Tool | What It Catches |
|---|---|
| axe DevTools (browser extension) | ~30-40% of WCAG issues automatically |
| Lighthouse Accessibility | High-level score + common issues |
| Keyboard (manual) | Navigation, focus, traps |
| Screen reader (manual) | Content order, announcements, labels |
| Zoom to 200% (manual) | Layout issues at larger text sizes |
Automated tools catch < 50% of issues. Manual testing with keyboard + screen reader is required.
Output
[CRITICAL] - [element/page] - [issue] - [WCAG criterion] - [fix]
[SERIOUS] - [element/page] - [issue] - [WCAG criterion] - [fix]
[MODERATE] - [element/page] - [issue] - [WCAG criterion] - [fix]
[MINOR] - [element/page] - [issue] - [WCAG criterion] - [fix]