The Journal

React & Performance3 min read

Accessibility from Day One: A Design Engineer's Responsibility

Accessibility isn't something you bolt on later. It's part of building good software. Learn how to bake a11y into your React components from the start.

Most teams find their accessibility bugs in an audit two weeks before launch, then scramble. It’s always the same three: a div that should’ve been a button, focus you can’t see, tap targets you can’t hit. Bake those in as defaults and the audit finds almost nothing.

Reach for real tags

The browser hands you focus, keyboard handling, and a role for free — but only if you use the right element. A button is focusable, fires on Enter and Space, and announces itself. A div with onClick does none of that until you rebuild it all by hand.

Use button for actions, a for navigation, a label tied to every input, and headings in order. Reach for role and aria-* only when no native element fits.

Screen readers narrate this structure — landmarks, headings, roles. A page that reads well as a plain outline reads well aloud.

Keep focus visible

Someone called the focus ring ugly, so outline: none shipped, and now keyboard users are lost. Never remove the ring — restyle it.

Use :focus-visible so it shows for keyboard and pen but not on mouse clicks. Give it a solid 2px outline with an offset and at least a 3:1 contrast ratio against the background. Being obvious is the whole point.

The default browser ring is fine, honestly. The bug is almost always someone deleting it, not the ring itself.

Make targets bigger

Tiny icon buttons are the top complaint on touch. Give interactive targets at least 44px by 44px — the number in Apple’s guidelines and WCAG alike.

If the glyph is 20px, extend the hit area with padding; don’t shrink the whole control. This helps everyone. Thumbs on phones miss small things constantly.

Space them out, too. Two 44px buttons jammed edge to edge still cause mis-taps; 8px between them fixes it.

Test with the keyboard

You don’t need a full audit to catch most of this. Put the mouse down and Tab through the page.

  • Can you reach every control, in an order that makes sense?
  • Can you see where you are the whole way?
  • Do Enter and Space activate what you’d expect?
  • Can you close a dialog with Escape?

Answer yes to those and you’ve handled what real audits flag. Build it in from day one and accessibility stops being a fire drill.

Frequently asked questions

How do I make React components accessible from the start?
Use real semantic elements so the browser gives you focus, keyboard handling, and roles for free: button for actions, a for navigation, a label tied to every input, and headings in order. Keep focus visible, make targets at least 44x44px, and test by tabbing through with the keyboard.
Is it okay to remove the focus outline with outline: none?
No. Removing the ring leaves keyboard users unable to see where they are. Restyle it instead, using :focus-visible so it shows for keyboard and pen but not mouse clicks, with a solid 2px outline, an offset, and at least a 3:1 contrast ratio against the background.
Why use a button element instead of a div with onClick?
A button is focusable, fires on Enter and Space, and announces itself to screen readers, all for free. A div with onClick does none of that until you rebuild every behavior by hand, so reach for role and aria attributes only when no native element fits.