JS Guide
HomeQuestionsSearchResources
Search

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsreact
PrevNext
react
mid
accessibility

How do you ensure accessibility (a11y) in React applications?

accessibility
a11y
aria
wcag
keyboard
screen-reader
Quick Answer

Ensure accessibility by using semantic HTML elements, proper ARIA attributes (aria-label, role), managing focus for dynamic content, supporting keyboard navigation, using htmlFor with labels, and testing with tools like eslint-plugin-jsx-a11y and screen readers.

Detailed Explanation

Core Principles:

  1. Semantic HTML First:

    • Use <button>, <nav>, <main>, <header> instead of divs
    • Semantic elements have built-in accessibility
  2. ARIA Attributes:

    • All aria-* attributes supported in JSX (hyphen-case)
    • Use aria-label, aria-describedby, aria-hidden, role
    • ARIA is a supplement, not replacement for semantic HTML
  3. Form Accessibility:

    • Use htmlFor (not for) to associate labels with inputs
    • Provide error messages accessible to screen readers
  4. Focus Management:

    • Use refs to manage focus programmatically
    • Trap focus in modals
    • Restore focus when dialogs close
  5. Keyboard Navigation:

    • All interactions must work with keyboard
    • Use onKeyDown alongside onClick
    • Proper tabIndex for custom interactive elements

Testing Tools:

  • eslint-plugin-jsx-a11y: Lint JSX for a11y issues
  • axe-core: Automated accessibility testing
  • Screen readers: VoiceOver (Mac), NVDA (Windows)

Code Examples

Semantic HTML and ARIA attributes
// BAD: Div soup
function BadNav() {
  return (
    <div className="nav">
      <div onClick={goHome}>Home</div>
      <div onClick={goAbout}>About</div>
    </div>
  );
}

// GOOD: Semantic HTML
function GoodNav() {
  return (
    <nav aria-label="Main navigation">
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
      </ul>
    </nav>
  );
}

// Accessible form with error messages
function AccessibleForm() {
  const [error, setError] = useState('');
  
  return (
    <form>
      <label htmlFor="email">Email Address</label>
      <input
        id="email"
        type="email"
        aria-describedby={error ? 'email-error' : 'email-hint'}
        aria-invalid={!!error}
      />
      <span id="email-hint" className="hint">
        We'll never share your email
      </span>
      {error && (
        <span id="email-error" className="error" role="alert">
          {error}
        </span>
      )}
      <button type="submit">Subscribe</button>
    </form>
  );
}

Resources

React Accessibility Documentation

docs

WAI-ARIA Authoring Practices

docs

eslint-plugin-jsx-a11y

docs

Related Questions

What is the difference between controlled and uncontrolled components in React forms?

mid
forms

How do you test React components with React Testing Library?

mid
react-testing-library
Previous
How does React Router work and what are its key features?
Next
How do you integrate UI component libraries with React and when should you use them?