Facebook iconA Developer’s Guide to Web Accessibility with HTML and React
Blogs/Technology

A Developer’s Guide to Web Accessibility with HTML and React

Jul 4, 20255 Min Read
Written by Amarnath Barpanda
A Developer’s Guide to Web Accessibility with HTML and React Hero

Imagine you're building a sleek, modern website,  it looks great, loads fast, and works beautifully on all devices. But one day, a user emails you: "I can't navigate your site with my screen reader. I couldn’t even subscribe to the newsletter." That’s when you realize something critical was missing accessibility. Accessibility isn't just a checklist; it's a way of ensuring everyone, regardless of ability, can use your website. From screen reader users to keyboard navigators, making your site inclusive means better UX for all. In this guide, we’ll demystify how to:

  • Use semantic HTML
  • Apply ARIA attributes the right way
  • Use aria-labelledby and aria-describedby
  • Avoid common accessibility anti-patterns

Let’s start building for everyone.

What is Semantic HTML?

Semantic HTML means using HTML tags that describe the content's meaning, not just its appearance. These tags tell browsers and assistive technologies what kind of content they’re interacting with, making your website more meaningful, especially for people using screen readers.

Good for screen readers, SEO, and other tools to understand your layout.

Common Semantic Elements and When to Use Them

TagUse ForExample

<header>

Page or section header

Top section of page

<nav>

Navigation links

Menus or link bars

<main>

Main content (1 per page)

Article, dashboard, etc.

<section>

Thematic grouping

Features, Services

<article>

Self-contained content

Blog post, comment

<aside>

Secondary content

Sidebars, ads, notes

<footer>

Page or section footer

Copyright, contact

<h1> to <h6>

Headings (semantic levels)

Titles and subtitles

<ul>, <ol>, <li>

Lists

FAQs, features

<form>

Group of input fields

Sign-up or search

<label>

Label for form field

Name, Email

<button>

Clickable actions

Submit, Next

<a>

Navigation links

Internal or external

<header>

Use For

Page or section header

Example

Top section of page

1 of 13

Use Semantic HTML First and Always

Start with HTML that means something. Don’t use a <div> or <span> just because it works visually use a <button> if it’s clickable, a <nav> if it’s navigation, and so on.

Why?

  1. Built-in accessibility
  2. Keyboard support (like Tab and Enter)
  3. Clear structure for screen readers

Example

<header>
  <nav>
    <a href="/">Home</a>
  </nav>
</header>

<main>
  <section>
    <h2>Features</h2>
    <p>Explore powerful tools.</p>
  </section>
</main>

<footer>
  <p>&copy; 2025</p>
</footer>

Use ARIA When HTML Alone Isn't Enough

ARIA stands for Accessible Rich Internet Applications. It allows you to fill in accessibility gaps when you're building custom UI components that native HTML doesn’t support well (like custom modals, tabs, dropdowns, etc.)

When to use ARIA

  1. You build a non-native interactive component
  2. You want to improve screen reader output
  3. You're updating content dynamically (e.g., live region)
Aria AttributeUse case

aria-label

Label for element with no visible text

aria-hidden=”true”

Hide from screen readers

aria-live

Announce dynamic content updates

aria-expanded

Toggled state (dropdowns, accordions)

aria-controls

Describes what element is controlled

role=”dialog”

Custom modals

role=”tablist”, role=”tab”

Custom tab interfaces

aria-label

Use case

Label for element with no visible text

1 of 7

Example

<button aria-expanded="false" aria-controls="dropdown1">Menu</button>
<ul id="dropdown1" hidden>
  <li>Item 1</li>
</ul>

When to avoid ARIA?

ARIA is powerful, but it can cause more harm than good if misused. You should avoid ARIA:

  • When a semantic HTML element can do the job. Use <button> instead of <div role="button">.
  •  If you’re not also implementing keyboard interaction. ARIA doesn’t add keyboard behavior.
  •  When you don’t fully test it with screen readers or assistive tech. Poor ARIA usage can confuse users.
  •  If it makes the DOM more complex without a clear benefit.

Partner with Us for Success

Experience seamless collaboration and exceptional results.

Example of What Not to Do:

<!-- Avoid this -->
<div role="button">Click me</div>

This lacks keyboard support, focus, and built-in accessibility.

Correct Semantic Version:

<button>Click me</button>

Use aria-labelledby to Replace or Combine Labels

Sometimes the visible label for an element comes from another part of the page. Use ‘aria-labelledby’ to associate it.

Example:

<div role="dialog" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Subscribe</h2>
  <p>Sign up for weekly updates.</p>
</div>

Use aria-describedby for Help Text, Errors, or Hints

This is helpful when you want to add supporting context, like form hints or validation messages.

Example:

<label for="email">Email</label>
<input id="email" aria-describedby="email-hint email-error" />
<p id="email-hint">We'll never share your email.</p>
<p id="email-error" style="color:red;">Email is required.</p>

Screen readers will read: “Email. We’ll never share your email. Email is required.”

Comparing Accessible and Inaccessible HTML Code in Practice

Sometimes seeing the difference makes it click. Here are the examples of accessible vs. non-accessible code:

Inaccessible Button Example

<div onclick="submitForm()">Submit</div>

No role or semantics

Not keyboard accessible

Accessible Button Example

<button onclick="submitForm()">Submit</button>

Screen reader-friendly

Built-in keyboard support

Inaccessible Form Input

<input type="text" placeholder="Your Name">

No label for screen readers

Accessible Form Input

<label for="name">Name</label>
<input type="text" id="name">

Proper label association

Partner with Us for Success

Experience seamless collaboration and exceptional results.

Accessibility in React Apps

React developers need to consider a few extra steps:

Use ‘htmlFor’ instead of ‘for’ in labels:

<label htmlFor="email">Email</label>
<input id="email" type="email" />

Manage keyboard events on custom components:

<div role="button" tabIndex={0} onKeyDown={handleKeyDown} onClick={handleClick}>
  Toggle
</div>

Use ‘aria-live’ for dynamically changing content:

<div aria-live="polite">{message}</div>

Consider accessible libraries like @radix-ui/react-*, reach-ui, or react-aria.

How Users Experience Your Site Without Accessibility

Accessibility is more than code; it's about real people. Imagine a user navigating your site using only a keyboard or a screen reader:

"I couldn't find the checkout button on your site. I had to ask a friend to help."

Or someone with color blindness:

"I didn’t realize the red box meant an error. There was no text or icon."

Designing with accessibility in mind makes sure everyone can access what you’ve built.

When to Use Semantic HTML vs ARIA?

GoalUse

Basic structure and meaning

Semantic HTML

Label an element (no text)

aria-label or aria-labelledby

Add extra instructions

aria-describedby

Dynamic or custom elements

ARIA roles/attributes

Hide decorative content

aria-hidden="true"

Basic structure and meaning

Use

Semantic HTML

1 of 5

Conclusion

Accessibility isn't about perfection,  it's about progress. The more thoughtful we are about the people who use our sites and apps, the more inclusive the web becomes for everyone. You don’t need to know everything or get it 100% right on the first try. What matters is the intention to include, the willingness to learn, and the small steps taken consistently.By choosing semantic HTML, using ARIA only when needed, and testing with real users or screen readers, you're creating something that welcomes everyone,  not just the majority.Accessibility isn't just a developer's responsibility, it's a mindset. And by reading this guide, you're already on the right path.

Keep going. Keep building. And keep including.

Author-Amarnath Barpanda
Amarnath Barpanda

Experienced Frontend Developer with a coder's heart. Mastering Shopify intricacies, crafting seamless shopping experiences. Let's elevate the e-commerce game. 🚀🌟

Phone

Next for you

Web Performance Optimization in 8 Steps Cover

Technology

Jul 4, 20259 min read

Web Performance Optimization in 8 Steps

Have you ever clicked away from a website because it took too long to load? You’re not alone. Most users expect websites to load in just a few seconds. If it doesn’t, they leave. A slow website can mean fewer visitors, lower sales, and poor search rankings. But the good news? You can fix it. This guide is here to help you make your website faster and smoother for everyone. We’ll walk you through 8 easy-to-follow steps, from checking your site’s speed to cleaning up messy code, compressing imag

What is Flutter Widget Tree: A Comprehensive Guide Cover

Technology

May 9, 20258 min read

What is Flutter Widget Tree: A Comprehensive Guide

Flutter, Google’s open-source UI toolkit, has transformed the way developers build cross-platform applications. Its declarative approach to UI design, combined with a rich set of widgets, enables developers to create stunning, performant, and responsive applications.  At the core of Flutter’s architecture lies the widget tree, a fundamental concept that every Flutter developer must understand to build effective and efficient applications.  In this blog post, we’ll dive deep into the Flutter wi

Stateful vs Stateless: Choosing the Right Backend Architecture Cover

Technology

May 9, 20257 min read

Stateful vs Stateless: Choosing the Right Backend Architecture

When building scalable web platforms, whether it’s a crypto trading exchange, a real-time chess application, or a standard e-commerce store, one of the foundational architectural choices you must make is whether to design your backend as stateful or stateless. This decision has significant implications for scalability, performance, reliability, and user experience. Let’s explore the fundamental differences between these two approaches, examine practical use cases, and understand how technologie