NashTech Blog

ARIA in React – Building Interfaces That Everyone Can Use (Part 2)

Table of Contents

Practical Patterns for Real-World Components

In Part 1, we discussed why ARIA exists and why accessibility is not optional in modern React applications.
In this part, we move from principles to practice.

ARIA becomes meaningful only when applied to real components, real state, and real user interactions.

This article focuses on common UI patterns that React developers build every day — and how ARIA makes them usable for everyone.

1. Buttons: The Simplest Thing We Still Get Wrong

The problem

<div onClick={onSubmit}>Submit</div>

This works visually, but it breaks:

  • Keyboard navigation
  • Screen readers
  • Expected behavior (Enter / Space)

The correct approach

<button onClick={onSubmit}>
  Submit
</button>

✅ Keyboard support
✅ Screen reader support
✅ No ARIA required

If a native element exists, use it. Always.

2. Custom Buttons: When ARIA Becomes Necessary

Sometimes design systems force us to build custom components.

Minimum acceptable pattern

<div
  role="button"
  tabIndex={0}
  aria-disabled={disabled}
  onClick={handleClick}
  onKeyDown={(e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      handleClick();
    }
  }}
>
  Submit
</div>

ARIA here is not decoration — it is damage control.

If you forget keyboard handling, ARIA becomes a lie.

3. Dropdowns & Menus: Communicating State

The problem

A dropdown visually opens, but assistive technology has no idea what happened.

The pattern

<button
  aria-haspopup="menu"
  aria-expanded={isOpen}
  aria-controls="menu"
  onClick={toggle}
>
  Options
</button>

<ul id="menu" role="menu" hidden={!isOpen}>
  <li role="menuitem">Edit</li>
  <li role="menuitem">Delete</li>
</ul>

What ARIA communicates:

  • This button controls a menu
  • The menu is open or closed
  • Items are selectable

ARIA describes relationships and state — not visuals.

4. Tabs: One of the Most Misimplemented Patterns

Tabs look simple. They are not.

Correct structure

<div role="tablist">
  <button
    role="tab"
    aria-selected={activeTab === 0}
    onClick={() => setActiveTab(0)}
  >
    Profile
  </button>

  <button
    role="tab"
    aria-selected={activeTab === 1}
    onClick={() => setActiveTab(1)}
  >
    Settings
  </button>
</div>

<div role="tabpanel" hidden={activeTab !== 0}>
  Profile content
</div>

<div role="tabpanel" hidden={activeTab !== 1}>
  Settings content
</div>

Key rules:

  • Only one tab is selected
  • Tab panels must match tabs
  • Keyboard navigation must be supported (Left / Right arrows)

ARIA defines meaning, but you must define behavior.

5. Forms: Error Handling That Respects Users

The problem

Visual error messages that screen readers never announce.

The solution

<input
  aria-invalid={!!error}
  aria-describedby={error ? 'email-error' : undefined}
/>

{error && (
  <span id="email-error">
    Invalid email address
  </span>
)}

What this achieves:

  • Errors are announced when focus enters the input
  • Context is preserved
  • Users are not forced to guess

Accessibility here is not about compliance — it is about respect.

6. Modals: Focus, Isolation, and Control

A modal without ARIA is a trap.

Minimum requirements

  • role="dialog"
  • aria-modal="true"
  • Focus moves into the modal
  • Focus is trapped
  • Focus returns on close
<div role="dialog" aria-modal="true">
  <h2 id="title">Confirm Action</h2>
  <p id="desc">Are you sure?</p>
</div>

Without this:

  • Screen readers read the background
  • Keyboard users get lost
  • Users cannot escape

If users cannot exit your modal, your UI has failed.

7. React State Is the Source of Truth

ARIA values must always reflect React state.

aria-expanded={isOpen}
aria-selected={isActive}
aria-busy={isLoading}

Never:

  • Hard-code ARIA values
  • Leave outdated states
  • Let UI and ARIA drift apart

ARIA must tell the truth — always.

8. Accessibility as a Code Review Standard

A mature team does not ask:

“Did we add ARIA?”

They ask:

  • Can this be used with keyboard only?
  • Does state change get announced?
  • Are native elements used correctly?
  • Is ARIA describing reality?

Accessibility is not a task.
It is a definition of done.

9. Conclusion: ARIA as a Craft, Not a Checklist

ARIA is not about attributes.
It is about empathy translated into code.

When you use ARIA correctly:

  • Your components become clearer
  • Your state management becomes more honest
  • Your UI becomes more resilient

A professional React developer does not ask how the UI looks.
They ask who it leaves behind.

Picture of lhpchihung

lhpchihung

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top