HTML5 Fundamentals

Accessibility: ARIA, Screen Readers & Best Practices

30 min Lesson 17 of 18

What is Web Accessibility?

Web accessibility means designing and building websites that everyone can use, including people with visual, auditory, motor, or cognitive disabilities. Approximately 16% of the global population lives with some form of disability, and accessible websites ensure that these users can perceive, understand, navigate, and interact with your content. Beyond inclusivity, accessibility also improves usability for all users and is a legal requirement in many countries.

Understanding WCAG Guidelines

The Web Content Accessibility Guidelines (WCAG) are the international standard for web accessibility, published by the W3C. They are organized around four core principles, often called POUR:

  • Perceivable -- Users must be able to perceive all information and interface components.
  • Operable -- Users must be able to operate all interactive elements.
  • Understandable -- Content and interfaces must be easy to understand.
  • Robust -- Content must work reliably across different technologies and assistive tools.

WCAG defines three conformance levels: Level A (minimum), Level AA (standard target for most websites), and Level AAA (highest, often impractical for entire sites). Most organizations aim for Level AA compliance.

Semantic HTML: The Foundation of Accessibility

Before reaching for ARIA attributes, always use the correct semantic HTML elements. Screen readers and assistive technologies already understand native HTML elements. A <button> is automatically focusable and keyboard-operable, while a <div> styled to look like a button is not.

Example: Semantic vs Non-Semantic Structure

<!-- Bad: Non-semantic, inaccessible -->
<div class="header">
    <div class="nav">
        <div class="link" onclick="goHome()">Home</div>
    </div>
</div>

<!-- Good: Semantic, accessible by default -->
<header>
    <nav>
        <a href="/">Home</a>
    </nav>
</header>

ARIA Roles

ARIA (Accessible Rich Internet Applications) roles define what an element is for assistive technologies. Use them only when semantic HTML cannot convey the purpose. Common landmark roles include:

  • role="navigation" -- Identifies a navigation section (equivalent to <nav>).
  • role="banner" -- Identifies the site header (equivalent to <header> when used as the page banner).
  • role="main" -- Identifies the primary content area (equivalent to <main>).
  • role="complementary" -- Identifies supporting content (equivalent to <aside>).
  • role="contentinfo" -- Identifies the page footer (equivalent to <footer>).

Example: ARIA Roles on a Page Layout

<div role="banner">
    <div role="navigation" aria-label="Main menu">
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/contact">Contact</a>
    </div>
</div>

<div role="main">
    <h1>Welcome to My Site</h1>
    <p>This is the primary content.</p>
</div>

<div role="contentinfo">
    <p>Copyright 2025</p>
</div>
Note: The first rule of ARIA is: do not use ARIA if a native HTML element already provides the behavior you need. Prefer <nav> over <div role="navigation">.

Essential ARIA Attributes

ARIA attributes provide additional context that assistive technologies rely on:

  • aria-label -- Provides an accessible name when visible text is absent.
  • aria-labelledby -- Points to the ID of an element that serves as the label.
  • aria-describedby -- Points to an element that provides a longer description.
  • aria-hidden="true" -- Hides an element from assistive technologies while keeping it visually present.
  • aria-live -- Announces dynamic content changes. Values: polite (waits) or assertive (interrupts).
  • aria-expanded -- Indicates whether a collapsible section is open or closed.

Example: ARIA Attributes in Practice

<!-- aria-label for icon-only buttons -->
<button aria-label="Close dialog">X</button>

<!-- aria-labelledby references another element -->
<h2 id="section-title">Our Services</h2>
<ul aria-labelledby="section-title">
    <li>Web Design</li>
    <li>Development</li>
</ul>

<!-- aria-describedby for form help text -->
<label for="password">Password</label>
<input type="password" id="password" aria-describedby="pw-help">
<span id="pw-help">Must be at least 8 characters.</span>

<!-- aria-live for dynamic status messages -->
<div aria-live="polite" id="status"></div>

<!-- aria-expanded for toggleable sections -->
<button aria-expanded="false" aria-controls="faq-1">What is ARIA?</button>
<div id="faq-1" hidden>ARIA stands for Accessible Rich Internet Applications.</div>

Keyboard Navigation

Many users navigate exclusively with a keyboard. All interactive elements must be reachable and operable via the Tab, Enter, Space, and Arrow keys. Key principles include:

  • tabindex="0" -- Adds a non-interactive element to the natural tab order.
  • tabindex="-1" -- Makes an element focusable via JavaScript but removes it from the tab order.
  • Never use tabindex values greater than 0, as they disrupt the natural document flow.
  • Always provide a visible focus indicator so users know where they are on the page.

Example: Skip Navigation Link

<body>
    <a href="#main-content" class="skip-link">Skip to main content</a>

    <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/contact">Contact</a>
    </nav>

    <main id="main-content">
        <h1>Page Title</h1>
        <p>Content starts here.</p>
    </main>
</body>

Writing Effective Alt Text

Every <img> element needs an alt attribute. Follow these guidelines:

  • Informative images -- Describe the content and function concisely (e.g., alt="Golden retriever playing in a park").
  • Decorative images -- Use an empty alt attribute: alt="". Screen readers will skip them.
  • Functional images (links or buttons) -- Describe the action, not the image (e.g., alt="Go to homepage").
  • Avoid starting with "Image of..." or "Picture of..." since the screen reader already announces it as an image.

Color Contrast and Visual Design

WCAG Level AA requires a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text. Never rely on color alone to convey meaning. For example, form error messages should include an icon or text label alongside the red color. Use tools like the WebAIM Contrast Checker to verify your color combinations.

Accessible Forms

Forms are critical interaction points. Every form control needs a visible, programmatically associated label. Group related fields with <fieldset> and <legend>, and provide clear error messages that identify the problem and suggest a fix.

Pro Tip: Test your website by navigating it using only the keyboard. Press Tab to move forward, Shift+Tab to move backward, Enter to activate links, and Space to toggle checkboxes and press buttons. If you get stuck or lose track of focus, your site has an accessibility problem.

Testing Tools and Checklist

Use these tools to audit your site:

  • axe DevTools -- Browser extension that scans for accessibility violations.
  • WAVE -- Web accessibility evaluation tool by WebAIM.
  • Lighthouse -- Built into Chrome DevTools, includes an accessibility audit.
  • Screen readers -- Test with NVDA (Windows, free), VoiceOver (macOS, built-in), or TalkBack (Android, built-in).
Common Mistake: Adding ARIA attributes without understanding them. Incorrect ARIA is worse than no ARIA at all, because it actively misleads assistive technologies and creates a confusing experience for users who depend on them.

Practice Exercise

Take any HTML page you have built in previous lessons and perform an accessibility audit. First, navigate the entire page using only the Tab key. Can you reach and activate every interactive element? Next, check that all images have meaningful alt text, all form fields have labels, and your heading hierarchy is logical (h1 followed by h2, not h1 followed by h4). Add a skip navigation link to the top of the page and include at least two ARIA attributes where they improve the experience. Finally, run the Lighthouse accessibility audit in Chrome DevTools and aim for a score above 90.