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>
<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>
- 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>
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>
);
};
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>
);
};
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>
🔹 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;
}
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" />
- Meaningful
alttext 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;
}
}
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>
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>
tabIndex="0"makes it focusable.onKeyDownenables 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>
<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
divfor 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