React Accessibility: Building WCAG 2.1 AA Compliant Components
Build accessible React components following WCAG 2.1 AA standards. Include proper ARIA, keyboard navigation, and focus management in React apps.
Introduction
React is powerful for building dynamic UIs but accessibility isn't automatic. 79% of React applications fail basic WCAG 2.1 AA tests. Missing ARIA attributes, focus management issues, and dynamic content problems plague React apps. Our guide helps developers build accessible React components and applications from day one.
Enterprise React apps face increasing ADA scrutiny. Recent lawsuits target major SaaS platforms using React. Poor React accessibility excludes 15-20% of potential users and damages employer brand. Accessibility is a engineering quality standard, not an afterthought.
Common Accessibility Issues
React components lack aria-label, aria-labelledby, and proper roles. Custom components don't announce their purpose to screen readers.
Dynamic content doesn't move focus when modals open. Focus trapping is broken. Users can't navigate to new content.
Custom React components respond only to clicks. Arrow keys, Tab navigation, and Enter/Space don't work. Keyboard users are locked out.
React image components render <img> tags without alt attributes. Dynamic images lack descriptions.
Form errors aren't announced. Validation messages are visual-only. Field requirements aren't programmatically indicated.
How to Fix Common Issues
Missing ARIA Labels on Custom Button
export function CloseButton() {
return <button onClick={() => close()}>×</button>
}export function CloseButton() {
return <button onClick={() => close()} aria-label="Close dialog">×</button>
}Icon buttons need aria-label. Always label custom controls with aria-label, aria-labelledby, or aria-describedby. Screen reader users must know what each button does.
Focus Not Managed in Modal
export function Modal({ isOpen, children }) {
return isOpen && <div>{children}</div>
}export function Modal({ isOpen, children }) {
const dialogRef = useRef(null)
useEffect(() => {
if (isOpen) dialogRef.current?.focus()
}, [isOpen])
return isOpen && <dialog ref={dialogRef}>{children}</dialog>
}Use useRef and useEffect to move focus when modals open. Use <dialog> element for semantic HTML. Return focus to trigger element on close.
Missing Alt Text on Images
<img src={productImage} /><img src={productImage} alt={`${productName} - ${productColor} available in sizes S-XXL`} />Always include alt attribute on <img> tags. Alt text should describe the image meaningfully. Empty alt (alt="") for decorative images only.
React-Specific Notes
React developers should use accessible React libraries: Headless UI, Radix UI, React Aria (Adobe), and React Hook Form provide accessible components. Install eslint-plugin-jsx-a11y to catch accessibility issues during development. Use Testing Library with testing-library/jest-dom for accessibility testing. Avoid inline onclick handlers; use semantic HTML.
Accessibility Statistics
850+
Lawsuits per year
79%
Sites non-compliant
60-90 hours
Avg fix time
Frequently Asked Questions
Should I use accessible component libraries?
How do I test accessibility in React?
What's the difference between aria-label and aria-labelledby?
How do I manage focus in React?
Check your website for free
Get your ADA, WCAG, privacy & security score in 90 seconds.
Related guides
Next.js Accessibility & WCAG 2.1 AA Compliance Guide
Build WCAG 2.1 AA accessible Next.js applications. Complete guide to server-side rendering, dynamic content, and accessible Next.js patterns.
HTML & CSS Accessibility Best Practices
Complete HTML and CSS accessibility guide for WCAG 2.1 AA compliance. Semantic HTML5, ARIA patterns, focus management, and accessible CSS techniques.
Angular Accessibility & WCAG 2.1 AA Compliance Guide
Build accessible Angular applications with WCAG 2.1 AA compliance. Complete guide to Angular accessibility patterns and CDK components.