REACT Accessibility

Accessibility (a11y) ensures that your React applications are usable by everyone, including people with disabilities. React makes it easier to build accessible web applications with built-in support for ARIA attributes, keyboard navigation, and screen reader compatibility.

1. Semantic HTML – The Foundation of Accessibility

Using proper HTML elements makes your app more accessible by default.

❌ Bad Example (Non-Semantic Elements)
<div onClick={() => console.log("Clicked!")}>Click me</div>

Try It Now

  • <div> is not an interactive element.
  • Screen readers won’t recognize it as a button.
✅ Good Example (Using <button>)
<button onClick={() => console.log("Clicked!")}>Click me</button>

Try It Now

  • Keyboard & screen reader friendly by default.
  • No need to manually handle focus.

Tip: Use <nav>, <article>, <header>, <footer>, <section>, and <main> instead of <div> for better readability.

2. ARIA (Accessible Rich Internet Applications) Attributes

ARIA helps enhance accessibility when using non-semantic elements.

Example: ARIA for Screen Readers
<button aria-label="Close" onClick={() => console.log("Closed")}>❌</button>

Try It Now

  • aria-label="Close" tells screen readers what the button does.

 

3. Managing Focus (Keyboard Navigation)

Users should be able to navigate using the keyboard (Tab, Enter, Esc).

Example: Focus on Modal Dialogs
import { useEffect, useRef } from "react";

const Modal = ({ onClose }) => {
  const modalRef = useRef(null);

  useEffect(() => {
    modalRef.current.focus(); // Auto-focus modal
  }, []);

  return (
    <div
      role="dialog"
      tabIndex="-1"
      ref={modalRef}
      onKeyDown={(e) => e.key === "Escape" && onClose()}
    >
      <p>Press ESC to close</p>
      <button onClick={onClose}>Close</button>
    </div>
  );
};

Try It Now

  • tabIndex="-1" makes the <div> focusable.
  • role="dialog" tells screen readers it’s a modal.
  • onKeyDown={(e) => e.key === "Escape" && onClose()} allows closing via ESC key.

 

4 Handling Forms Accessibly

Forms should include labels, error messages, and ARIA attributes.

Example: Accessible Form
const LoginForm = () => {
  return (
    <form>
      <label htmlFor="email">Email</label>
      <input id="email" type="email" aria-required="true" />

      <button type="submit">Login</button>
    </form>
  );
};

Try It Now

  • htmlFor="email" correctly associates the label with the input field.
  • aria-required="true" tells screen readers this field is mandatory.

5. Skip Links (Jump to Main Content)

For keyboard users, skip links help jump past navigation menus.

Example: Skip Navigation
<a href="#main-content" className="skip-link">Skip to main content</a>

<main id="main-content">
  <h1>Welcome to My Website</h1>
</main>

Try It Now

🔹 Style .skip-link to appear only when focused:

.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px;
}

.skip-link:focus {
  top: 0;
}

Try It Now

Helps screen reader & keyboard users navigate faster.

 

6. Alternative Text for Images

Screen readers rely on alt text to describe images.

Example: Accessible Images
<img src="profile.jpg" alt="John Doe's Profile Picture" />

Try It Now

  • Meaningful alt text improves screen reader usability.
  • For decorative images, use alt="" to hide them from screen readers.

7. Color Contrast & Dark Mode

Ensure text is readable for users with low vision or color blindness.

 

Example: High Contrast Mode
:root {
  --text-color: #333;
  --bg-color: #fff;
}

@media (prefers-contrast: high) {
  :root {
    --text-color: #000;
    --bg-color: #f5f5f5;
  }
}

Try It Now

Automatically adjusts for users with high-contrast settings.

 

8. Avoid onClick Only for Interactive Elements

Some users can’t use a mouse, so always support keyboard interactions.

❌ Bad Example (No Keyboard Support)
<div onClick={() => console.log("Clicked!")}>Click me</div>

Try It Now

Keyboard users can’t “click” this div!

✅ Good Example (Keyboard Accessible)

 

<div
  role="button"
  tabIndex="0"
  onClick={() => console.log("Clicked!")}
  onKeyDown={(e) => e.key === "Enter" && console.log("Clicked!")}
>
  Click me
</div>

Try It Now

  • tabIndex="0" makes it focusable.
  • onKeyDown enables Enter key interaction.

9. Accessible Tables

Tables should include headers and descriptions for clarity.

Example: Proper Table Markup
<table>
  <caption>Monthly Sales Report</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Sales</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January</td>
      <td>$10,000</td>
    </tr>
  </tbody>
</table>

Try It Now

  • <caption> provides a table summary.
  • <th scope="col"> properly defines column headers.

10. Testing Accessibility (a11y)

Use Browser DevTools
  • Chrome: Right-click → Inspect → Lighthouse → Accessibility Audit.
  • Firefox: Inspect → Accessibility Panel.

 

Use Screen Readers
  • Windows: NVDA (free)
  • Mac: VoiceOver (built-in)
  • Chrome: ChromeVox (extension)

 

Automated Testing Tools
  • 🛠️ axe DevTools (Chrome extension)
  • 🛠️ react-a11y (npm package)

🔹 Summary – React Accessibility Checklist

  • Use semantic HTML (avoid div for buttons)
  • Add ARIA attributes when necessary
  • Ensure keyboard navigation (focus, ESC to close modals)
  • Provide labels & error messages for forms
  • Use skip links for navigation
  • Add alt text for images
  • Ensure high contrast for better readability
  • Support keyboard & mouse interactions
  • Use accessible tables for data
  • Test with Lighthouse, screen readers, and a11y tools