How to Make Your React App Truly Accessible: More Than Just Color Contrast
Yacine Ouardi

Let’s get one thing out of the way: accessibility is not a feature. It’s not something you “add later” or sprinkle in after the final commit. It’s a fundamental part of building for the web. But in reality, most teams don’t treat it that way — and I’ve been guilty of that myself.
I used to think accessibility was just about using the right color contrast or maybe throwing in an aria-label
here and there. But then I started navigating one of my own React apps using only the keyboard. That was a frustrating wake-up call.
The page looked fine, sure. Visually, it was clean, modern, even elegant. But try tabbing through it: you’d end up stuck in a loop of hidden elements, completely unable to reach a critical button. And don’t get me started on modal dialogs. I had built them using a third-party component that didn’t trap focus. When opened, it let the user tab right out of it and land on elements behind the overlay. That was the moment I realized I hadn’t just missed accessibility — I had ignored it.
Here’s the thing: real accessibility goes far beyond color contrast. If your app isn’t navigable by keyboard, or if a screen reader user can’t make sense of your layout, then it’s not accessible. Period.
Let’s talk about the most overlooked but absolutely essential part: keyboard navigation.
Keyboard Navigation: The Silent Guardian of UX
Have you ever used your app without a mouse? Try it. Hit Tab
and see what happens.
Can you reach every interactive element? Are the focus states visible? Is the focus order logical?
Many developers forget that not all users navigate the web visually. Some use a keyboard exclusively — either because they rely on assistive tech or because of physical limitations. And if your app doesn’t support that, you’re shutting the door in their face.
Common Issues I’ve Encountered:
- Missing focus outlines: Designers often remove them for aesthetics. Don’t. If you must style them, at least keep them visible.
- Inconsistent tab order: Especially with flex layouts or complex modals. Use semantic HTML and logical DOM order.
- Custom components without
tabIndex
: Ever built a fancy dropdown that’s impossible to focus? Been there. - Non-interactive elements acting like buttons: If it looks like a button, make sure it’s a
<button>
, not a<div>
with anonClick
.
How to Actually Make Your React App Accessible
Here’s a brief checklist I follow now for any new feature:
✅ Use Semantic HTML
Don’t reinvent the wheel. Use <button>
, <nav>
, <header>
, <main>
, <section>
, and <form>
. Assistive tech understands these.
✅ Trap Focus in Modals
Use libraries like focus-trap-react
or manually trap focus inside modals so users don’t tab to background content.
jsx
// A basic modal with focus trap (simplified)
import FocusTrap from 'focus-trap-react';
export default function MyModal({ isOpen, onClose }) {
if (!isOpen) return null;
return (
<FocusTrap>
<div role="dialog" aria-modal="true">
<h2>Confirm Action</h2>
<button onClick={onClose}>Cancel</button>
<button>Confirm</button>
</div>
</FocusTrap>
);
}
✅ Use aria-*
Attributes Wisely
They’re powerful but often misused. If you're building custom components, they help bridge gaps for screen readers.
aria-expanded
,aria-haspopup
,aria-label
,aria-live
— learn them.- Use them only when necessary. Don’t add
aria-label
to things that already have a visible label.
✅ Visible Focus States
Use Tailwind or custom styles, but make sure they’re obvious.
jsx
<button className="focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit
</button>
✅ Test with a Screen Reader and Keyboard
Don’t assume. Try VoiceOver (Mac) or NVDA (Windows) and see what your app sounds like.
Accessibility Is a Mindset
Here’s the uncomfortable truth: many accessibility issues exist not because developers are lazy, but because they were never taught to think about users beyond themselves.
I know I wasn’t. It wasn’t until I tried using my own app without a mouse — and failed — that I truly saw the problem.
We need to treat accessibility the same way we treat performance or security: as a core part of quality software.
Yes, it takes a bit more time.
Yes, it adds a few extra steps.
But it makes your work usable by everyone. And isn’t that the point?
Final Thoughts
If you’re building with React, you already have the tools to make your app accessible. The question is: are you using them?
Don’t wait for someone to report a bug before you fix it. Don’t assume your app “just works” for everyone because it works for you. Accessibility isn’t an add-on. It’s your job.
Start by testing keyboard navigation. Then go deeper.
And please, leave those div
buttons in the past.