---
id: daffy0208/ai-dev-standards/accessibility-engineer
version: "6bb99c21"
license: MIT
install: manual
updated: 2025-12-25
---
# Accessibility Engineer — This skill equips developers with the knowledge and techniques needed to design and build web applications that meet WCAG 2.1 AA accessibility standards. Learn how to identify barriers, implement inclusive patterns, and verify compliance across your projects. Gain hands-on experience making digital experiences usable for everyone.
Publisher: daffy0208 · Stars: 32 · Updated: 2025-12-25
Install (manual): `git clone https://github.com/daffy0208/ai-dev-standards`
## SKILL.md
# Accessibility Engineer
Build for everyone - accessibility is not optional.
## Core Principle
**Accessibility is a civil right, not a feature.**
1 in 4 adults in the US has a disability. Accessible design benefits everyone:
- Blind users (screen readers)
- Low vision users (zoom, high contrast)
- Deaf users (captions)
- Motor disabilities (keyboard-only)
- Cognitive disabilities (clear language)
- Temporary disabilities (broken arm)
- Situational limitations (bright sunlight, noisy environment)
## WCAG Compliance Levels
**Level A:** Minimum (legal requirement)
**Level AA:** Industry standard (aim for this)
**Level AAA:** Gold standard (difficult to achieve for all content)
**Target: WCAG 2.1 AA compliance**
---
## Pillar 1: Semantic HTML
### Use the Right Elements
```jsx
// ❌ Bad: Divs for everything (no semantic meaning)
// Skipped h2, h3
```
### Landmarks
```jsx
{/* Main content */}
```
---
## Pillar 2: Keyboard Navigation
### All Interactive Elements Must Be Keyboard Accessible
```jsx
// ✅ Button is keyboard accessible by default
// ❌ Div requires extra work
Click me
// Can't tab to it!
// ✅ If you must use div, add keyboard support
{
if (e.key === 'Enter' || e.key === ' ') {
handleClick()
}
}}
>
Click me
```
### Tab Order
```jsx
// ✅ Natural tab order (follows DOM order)
Help
// ❌ Don't use tabIndex > 0 (breaks natural order)
// Anti-pattern!
// ✅ tabIndex=-1 to remove from tab order
Not keyboard focusable
```
### Focus Management
```jsx
// Modal: Trap focus inside
function Modal({ isOpen, onClose, children }) {
const modalRef = useRef()
useEffect(() => {
if (!isOpen) return
// Focus first focusable element
const firstFocusable = modalRef.current.querySelector('button, input, a')
firstFocusable?.focus()
// Trap focus
function handleTab(e) {
if (e.key !== 'Tab') return
const focusableElements = modalRef.current.querySelectorAll(
'button, input, a, [tabindex]:not([tabindex="-1"])'
)
const first = focusableElements[0]
const last = focusableElements[focusableElements.length - 1]
if (e.shiftKey) {
if (document.activeElement === first) {
last.focus()
e.preventDefault()
}
} else {
if (document.activeElement === last) {
first.focus()
e.preventDefault()
}
}
}
document.addEventListener('keydown', handleTab)
return () => document.removeEventListener('keydown', handleTab)
}, [isOpen])
return isOpen ? (
{children}
) : null
}
```
### Skip Links
```jsx
// Allow keyboard users to skip navigation
Skip to main content
{/* Main content */}
// CSS
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
}
.skip-link:focus {
top: 0;
}
```
---
## Pillar 3: ARIA Attributes
### Only Use ARIA When Semantic HTML Isn't Enough
```jsx
// ✅ Semantic HTML (no ARIA needed)
// ❌ Unnecessary ARIA
// ✅ ARIA needed (custom widget)
Tab 1
```
### Common ARIA Attributes
**aria-label** - Provides accessible name:
```jsx
```
**aria-labelledby** - References another element:
```jsx