ARIA Labels & Semantic HTML: Building for Screen Readers

Understanding Screen Reader Accessibility

Screen readers are software programs that read web content aloud to users. Approximately 2.2 billion people worldwide have visual impairments, and many rely on screen readers to access digital content. A screen reader's effectiveness depends entirely on how websites are coded.

Screen readers interpret HTML markup and present it as structured information. A screen reader announces headings, navigates between form fields, identifies buttons, and announces interactive element states. The better your HTML markup describes your content structure and functionality, the better the screen reader experience.

HTML includes semantic elements specifically designed to convey meaning. These elements communicate structure and function inherently. ARIA (Accessible Rich Internet Applications) provides additional markup for complex components that HTML doesn't adequately describe. Understanding when to use semantic HTML and when to supplement it with ARIA is the key to accessible development.

Legal Disclaimer

A11yscan is not a law firm and does not provide legal advice. We operate under best practices based on WCAG Guidelines, ADA requirements, and applicable jurisdictions. Courts don't always agree on terms and expectations for web accessibility, and legal standards can vary by jurisdiction. However, an accessible website works better for all users regardless of legal requirements. For specific legal guidance, consult with a qualified attorney specializing in accessibility law.

Semantic HTML: The Foundation

Semantic HTML uses tags that inherently communicate meaning. A `<button>` element means "this is a button." A `<nav>` element means "this is navigation." A `<h1>` element means "this is a heading." Screen readers understand these meanings and present them appropriately.

Core Semantic Elements

<nav> - Indicates primary navigation. Screen readers announce this, allowing users to skip navigation or navigate directly to it.

<main> - Identifies primary content. Used with skip links to help keyboard users navigate directly to content.

<article> - Indicates independent, self-contained content. Screen readers announce article boundaries.

<section> - Groups related content. Screen readers can navigate between sections.

<aside> - Indicates supplementary content. Screen readers announce this as secondary content.

<header> and <footer> - Indicate header and footer areas. Screen readers announce these structural landmarks.

<h1>–<h6> - Indicate heading hierarchy. Screen reader users navigate by headings and expect proper hierarchy.

<button> - Creates keyboard-accessible button. Includes automatic focus management and keyboard support.

<a> - Creates link. Keyboard-accessible and properly announced by screen readers.

<label> - Associates text with form input. Screen readers announce label content when input receives focus.

Why Semantic HTML Is Superior to ARIA

When a semantic element can accomplish your goal, use it instead of ARIA. A `<button>` element automatically provides keyboard support, focus management, and proper screen reader announcement. Creating a button with a div and ARIA requires recreating all this functionality.

The principle is straightforward: semantic HTML first, ARIA second. Use semantic elements whenever possible, then use ARIA to supplement where necessary.

ARIA Attributes: When and How to Use Them

ARIA (Accessible Rich Internet Applications) provides attributes that supplement semantic HTML for complex components or situations where semantic HTML doesn't provide adequate information.

ARIA Landmarks

While semantic elements are preferred, ARIA role attributes can provide landmark information:

<nav role="navigation">...</nav>
<main role="main">...</main>
<div role="complementary">Sidebar</div>

ARIA Labels and Descriptions

aria-label provides a label for elements that don't have visible text labels. Icon-only buttons commonly use aria-label:

<button aria-label="Close menu">✕</button>

aria-labelledby links an element to another element that labels it:

<h2 id="modal-title">Confirm Delete</h2>
<div role="dialog" aria-labelledby="modal-title">...</div>

aria-describedby links an element to descriptive content:

<input id="password" aria-describedby="pwd-hint">
<p id="pwd-hint">Password must be 8+ characters</p>

ARIA States and Properties

aria-hidden="true" hides elements from screen readers. Use this for decorative elements:

<img src="star.svg" alt="" aria-hidden="true">

aria-disabled="true" indicates disabled state:

<button aria-disabled="true">Submit</button>

aria-checked, aria-selected, aria-pressed indicate component state:

<div role="checkbox" aria-checked="true">...</div>

aria-expanded indicates whether a collapsible section is open:

<button aria-expanded="false" aria-controls="menu">Menu</button>

aria-live announces dynamic content updates:

<div aria-live="polite">Item added to cart</div>

ARIA Roles: When You Need Them

ARIA roles assign semantic meaning to elements that lack semantic HTML equivalents. However, using semantic elements eliminates the need for most role attributes.

Appropriate Role Usage

Use ARIA roles only when semantic HTML doesn't provide the needed meaning. For example:

✅ Correct: `<button>Open Menu</button>` (semantic element, no ARIA needed)

❌ Incorrect: `<div role="button">Open Menu</div>` (recreates button with ARIA and requires additional keyboard handling)

✅ Appropriate ARIA: `<div role="dialog">...</div>` (no semantic HTML element exists for dialogs)

Common ARIA Roles

dialog - Indicates a modal dialog. Must manage focus and handle Escape to close.

alert - Announces important information immediately. Screen readers interrupt to announce alerts.

tab, tablist, tabpanel - Structures tab components with proper keyboard navigation.

menuitem, menu - Structures menu components with arrow key navigation.

slider - Indicates a range input. Arrow keys adjust value.

Common Mistakes and Anti-Patterns

Understanding what not to do helps ensure your markup is genuinely accessible.

Mistake 1: Recreating Native Elements with ARIA

❌ Wrong: `<div role="button" onclick="...">Click me</div>`

This requires manual implementation of keyboard support, focus management, and screen reader announcements.

✅ Right: `<button>Click me</button>`

Mistake 2: Excessive ARIA

❌ Wrong: Adding ARIA to elements that already have semantic meaning.

<h1 role="heading">Page Title</h1>

The `<h1>` element already indicates a heading. The role attribute is redundant.

Mistake 3: Forgetting Keyboard Support

Using ARIA to add screen reader support without ensuring keyboard support creates barriers for keyboard-only users. A custom button with aria-label still needs keyboard handlers.

Use semantic `<button>` which handles this automatically.

Mistake 4: Incorrect Heading Hierarchy

❌ Wrong: Jumping heading levels or using headings out of order.

<h1>Page Title</h1>
<h3>Subsection</h3> <!-- Should be h2 -->

Mistake 5: Using aria-label Incorrectly

❌ Wrong: Using aria-label on text elements that already have visible text.

<h2 aria-label="Important Section">Important Section</h2>

The visible text serves as the label. aria-label isn't needed.

Practical Implementation: Building an Accessible Form

Let's walk through building an accessible form with semantic HTML and appropriate ARIA:

Semantic HTML Approach

<form>
  <label for="email">Email Address</label>
  <input id="email" type="email" required>

  <label for="message">Message</label>
  <textarea id="message"></textarea>

  <button type="submit">Send</button>
</form>

Adding ARIA for Enhanced Support

<form>
  <label for="email">Email Address</label>
  <input id="email" type="email" required aria-describedby="email-help">
  <small id="email-help">We'll never share your email</small>

  <label for="message">Message</label>
  <textarea id="message" aria-describedby="msg-count"></textarea>
  <div id="msg-count" aria-live="polite">0 characters</div>

  <button type="submit">Send</button>
</form>

Adding Error Handling

<form>
  <label for="email">Email Address</label>
  <input id="email" type="email" required aria-invalid="false" aria-describedby="email-error">
  <span id="email-error" role="alert"></span>
</form>

On validation error, set aria-invalid="true" and populate the error span with the error message. The role="alert" ensures screen readers announce the error immediately.

Testing Semantic HTML and ARIA

Verify your markup works with screen readers by testing with actual assistive technology.

Screen Reader Testing

Test with free screen readers like NVDA (Windows) or VoiceOver (macOS/iOS). Navigate your page and verify that all content is accessible and properly announced.

Automated Testing

Tools like axe DevTools identify ARIA misuse and incorrect semantic markup. However, automated tools can't verify that your ARIA implementation actually works with screen readers—human testing is essential.

Developer Tools Inspection

Modern browser developer tools display accessibility information. Right-click elements and select "Inspect" to see the accessibility tree, showing how assistive technology perceives your markup.

Manual Code Review

Review code to ensure semantic HTML is used when possible and ARIA supplements rather than replaces semantic meaning.

Key Takeaways

  • Semantic HTML is the foundation of screen reader accessibility; use semantic elements whenever possible.
  • ARIA supplements semantic HTML for complex components where semantic HTML doesn't provide adequate meaning.
  • Never use ARIA to recreate native elements; use semantic HTML instead.
  • ARIA labels should only be used when visible text labels aren't available or appropriate.
  • Maintain proper heading hierarchy; screen reader users navigate using headings.
  • Use aria-live for dynamic content that updates without page reload.
  • Test your implementation with actual screen readers; automated tools identify issues but can't verify actual usability.
  • Semantic HTML + ARIA + keyboard support = comprehensive screen reader accessibility.

Resources

Check Your Semantic Markup

Get a professional audit to identify ARIA misuse and missing semantic HTML, with expert recommendations for improvement.