Topics

On this page

Last updated on Dec 5, 2025

Accessibility

Web accessibility (also referred to as a11y) is the design and creation of websites that can be used by everyone. Accessibility support is necessary to allow assistive technology to interpret web pages.

React fully supports building accessible websites, often by using standard HTML techniques.

WCAG – Web Content Accessibility Guidelines

It is an internationally recognized set of guidelines developed by the World Wide Web Consortium (W3C) to make web content more accessible to people with disabilities.

WCAG Principles (POUR)

The guidelines are built around four principles:

  1. Perceivable: Content must be presented in ways users can perceive (e.g., text alternatives for images, captions for video).
  2. Operable: Users must be able to interact with content (e.g., full keyboard navigation, visible focus states).
  3. Understandable: Content and UI must be easy to understand (e.g., clear labels, predictable navigation).
  4. Robust: Content should be compatible with assistive technologies (e.g., screen readers).

WCAG Conformance Levels (A, AA, AAA)

There are three levels:

LevelMeaningImportance
AMinimum requirementsBasic accessibility for many users
AAMid-level, industry standardAddresses the biggest barriers for people with disabilities
AAAHighest levelOften used by governments or for specialized accessibility needs

WCAG 2.1 Level AA – What it means:

We should at least aim for WCAG 2.1 Level AA.
Level AA includes all Level A requirements plus additional rules for usability and inclusivity:

WCAG Checklist

The following WCAG checklists provide an overview:

WAI- ARIA: Web Accessibility Initiative – Accessible Rich Internet Applications

ARIA is a set of attributes defined by the W3C (World Wide Web Consortium) to make web applications and dynamic content more accessible to people who use assistive technologies like screen readers.

Why ARIA exists?

Since React apps often build custom UI components (modals, dropdowns, tabs, sliders) that don’t always map cleanly to native HTML semantics, ARIA ensures that these components are correctly understood by assistive tools.

Why ARIA matters in React?


Note that all aria-* HTML attributes are fully supported in JSX. Whereas most DOM properties and attributes in React are camelCased, these attributes should be hyphen-cased (also known as kebab-case, lisp-case, etc.) as they are in plain HTML.

<input
  type="text"
  aria-label={labelText}
  aria-required="true"
  onChange={onchangeHandler}
  value={inputValue}
  name="name"
/>

ARIA best practices in React

Structural Elements: Headings & Lists

Structure is how assistive tech (and search engines) understand your page. Use semantic HTML first and keep the outline predictable. This section covers headings and lists in React, with code patterns, do/don’ts, and testing tips.

A. Headings

Goals

Core rules

Example    

export default function ProductPage() {
  return (
    <main>
      <h1>Travel Mugs</h1>

      <section aria-labelledby="filters-heading">
        <h2 id="filters-heading">Filters</h2>
        {/* … */}
      </section>

      <section aria-labelledby="results-heading">
        <h2 id="results-heading">Results</h2>
        {/* … */}
      </section>
    </main>
  );
}

B. Lists

Goals

Choose right list type

Don’t

Sectioning & Landmarks (works with headings)

<a href="#main" className="sr-only focus:not-sr-only">Skip to main content</a>
<main id="main"></main>

Links (<a>) are one of the most important structural elements on the web. For React apps, ensuring links are semantic, accessible, and usable with both keyboard and assistive technologies is essential.

1) Always use real <a> elements

// ✅ Correct
<a href="/about">About Us</a>

// ❌ Wrong (not accessible as a link)
 navigate('/about')}>About Us</div>
// ✅ Good
<a href="/pricing">View pricing plans</a>

// ❌ Bad
<a href="/pricing">Click here</a>

// For repeated links
<a href={`/articles/${id}`}>
  Read more <span className="sr-only">about {title}</span>
</a>

2) Maintain a visible focus style

a:focus-visible {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
}

Buttons

<button aria-label="Close dialog">
  <CloseIcon aria-hidden="true" />
</button>
<button
  aria-expanded={open}
  aria-controls="menu"
  onClick={() => setOpen(!open)}
>
  Menu
</button>

Form elements

<label htmlFor="email">Email</label>
<input id="email" type="email" />
<fieldset>
  <legend>Delivery Options</legend>
  <label><input type="radio" name="delivery" value="standard" /> Standard</label>
  <label><input type="radio" name="delivery" value="express" /> Express</label>
</fieldset>
<label htmlFor="username">Username</label>
<input id="username" aria-describedby="username-help" />
<p id="username-help">Must be at least 6 characters.</p>

Modals & dialogs

Carousels (Slide Show)

<div aria-live="polite" class="sr-only" role="status">
  Slide 4 of 9. Offer for Abacos, Bahamas now visible.
</div>
<div role="group" aria-roledescription="slide" aria-label="Offer for British Virgin Islands" tabindex="-1">
  ...Slide content....
</div>

Images

Accessible images make your UI usable for people who rely on assistive tech (screen readers, braille displays), and they improve SEO and performance. This guide focuses on what to show and how to code it in React.

Always choose the right alternative text

Based on the correct choice of alt text, images can be divided into four categories:

A. Informative images (convey meaning)

<img src="/team/alex.jpg" alt="Alex Nguyen, Customer Success Manager" />

For functional images, the accessible name must describe the action or destination, not the picture.

<a href="/cart">
  <img src="/icons/cart.svg" alt="View cart" />
</a>

<button aria-label="Close dialog">
  <img src="/icons/close.svg" alt="" aria-hidden="true" />
</button>

C. Decorative images (purely visual / redundant)

Use an empty alt or role=”presentation” so screen readers skip it.

<img src="/decor/gradient.png" alt="" />
or
<img src="/decor/gradient.png" role="presentation" />

Inline SVG icons used as decoration

<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24"></svg>

D. Complex images (charts, diagrams, infographics)

Provide a short alt + a longer description nearby. Use <figure> and <figcaption> or reference text with aria-describedby.

<figure>
  <img src="/charts/sales-q4.png" alt="Q4 sales by region bar chart" aria-describedby="chart-desc" />
  <figcaption id="chart-desc">
    North America leads with $2.1M, followed by EMEA $1.6M, APAC $1.1M. YoY growth 12%.
  </figcaption>
</figure>

Avoid images of text

Testing accessible images

In-Page tabbed component – tabs pattern

There are two most common tab patterns:

Behaviour

When to use automatic vs manual activation?

Roles, states and properties

Tables

Color contrast

Tools and packages

POUR principles ref 

Perceivable

Operable

Understandable

Robust

How to make accessible UI

Start with Radix/Shadcn components

WAI-ARIA compliance – Correct ARIA roles, states, and properties (aria-expanded, aria-controls, role="dialog", etc.) are managed for you.

Full keyboard navigation – All components are operable with a keyboard (e.g., arrow keys for menus, Tab for focus, Enter/Space for activation, Esc for dismissal).

Focus management – It intelligently handles focus, trapping it within modals and returning it to the trigger element when the modal is closed. This is a huge win for accessibility and is difficult to implement correctly from scratch.

Manage color and contrast

Provide accessible labels

Testing for accessibility

Do read our article on All about Web Accessibility, WCAG and making WordPress website more compliant.


Credits

Authored by Sayed Sayed Sayed Taqui Director of Engineering – React , Imran Imran Imran Sayed Senior WordPress Engineer , Ayush Ayush Ayush Nirwal Senior Software Engineer , Amoghavarsha Amoghavarsha Amoghavarsha Kudaligi Senior Software Engineer , Mayank Mayank Mayank Rana Senior Software Engineer