A11y Web Accessibility

Build inclusive web experiences with WCAG, ARIA, keyboard, forms, and testing workflows.

ARIA Roles & Attributes

Web Accessibility Lesson 2 of 10 ~11 min read

Overview

Expose custom widget roles, names, states, and relationships correctly.

ARIA Roles & Attributes makes the interface usable for more people and more devices. The goal is not only passing an automated score, but making names, focus, state, errors, and reading order understandable.

Core Ideas

  • For ARIA Roles & Attributes, start with the keyboard and visible labels.
  • Expose the right name, role, value, and state for interactive controls.
  • Use clear error messages and do not rely on color alone.
  • Validate with tools, then confirm manually with real interaction.

Step by Step

  1. Build the ARIA Roles & Attributes pattern with semantic HTML first.
  2. Tab through the interface and confirm focus order.
  3. Check labels, descriptions, live messages, and error states.
  4. Use an automated tool after manual checks to catch missed details.

Beginner Explanation

ARIA Roles & Attributes teaches how ARIA can expose names, roles, states, and relationships when native HTML cannot describe a custom interface by itself.

ARIA is powerful, but it does not add keyboard behavior or fix invalid HTML. A custom button still needs keyboard support if it is not a real button.

Beginners should first ask whether a native element already solves the problem before adding roles and aria-* attributes.

Before You Start

  • Before practicing ARIA Roles & Attributes, identify the task a user is trying to complete.
  • List the interactive elements and confirm each one has a visible label or clear text.
  • Tab through the UI once before changing code so you know the current focus order.
  • Check whether information is conveyed only by color, position, motion, or icon shape.
  • Keep a notes list for issues found by keyboard testing, screen reader testing, and automated tools separately.

Key Accessibility Concepts

  • Accessible name: the text assistive technology uses to identify a control.
  • Role: what the element is, such as button, dialog, tab, or alert.
  • State: current condition, such as aria-expanded, aria-selected, aria-invalid, or aria-pressed.
  • Relationship: connections such as aria-controls, aria-describedby, aria-labelledby, or aria-live.

Plain-English Glossary

  • Accessible name: the label announced for a control, link, image, or region.
  • Role: the type of element or widget exposed to assistive technology.
  • State: current information such as expanded, selected, pressed, invalid, checked, or disabled.
  • Focus order: the sequence keyboard users follow when pressing Tab and Shift+Tab.
  • Landmark: a page region such as nav, main, header, footer, aside, or form.
  • Live region: an area that announces important dynamic updates.
  • Alt text: text alternative for an image when the image communicates information.
  • Assistive technology: tools such as screen readers, magnifiers, switch devices, voice control, and captions.

What You Will Learn

  • Explain the accessibility risk that ARIA Roles & Attributes solves.
  • Identify names, roles, states, labels, focus order, and errors in a real interface.
  • Update the code editor example without breaking keyboard or screen reader behavior.
  • Separate automated-tool findings from manual usability findings.

Where You Use This in Real Projects

You use ARIA Roles & Attributes in login pages, checkout flows, dashboards, menus, dialogs, search forms, media pages, image galleries, article pages, admin panels, and design systems.

Accessibility work is easiest when it is built into components from the start: buttons, links, inputs, alerts, dialogs, tabs, accordions, cards, navigation, and tables.

A beginner should practice small pieces first, then test the full task flow from page load to success or error recovery.

Browser and Assistive Technology Notes

  • Different browsers and assistive technologies may announce the same pattern slightly differently, so test the behavior, not only the exact wording.
  • Native HTML controls usually provide stronger cross-browser behavior than custom div-based controls.
  • Do not hide important text with display: none if assistive technology needs to read it.
  • Use visually hidden helper text only when the text is useful for non-visual users and not a substitute for visible instructions.
  • Retest after CSS and JavaScript changes because visual updates can accidentally hide labels, focus rings, and error messages.

Code Example

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

<nav id="menu" hidden aria-label="Primary">
  <a href="/learn">Learn</a>
</nav>

<div role="status" aria-live="polite">Saved</div>

Another Example

<button id="menuButton" type="button" aria-expanded="false" aria-controls="accountMenu">
  Account options
</button>
<ul id="accountMenu" hidden>
  <li><a href="/profile">Profile</a></li>
  <li><a href="/settings">Settings</a></li>
</ul>

<script>
  const button = document.querySelector('#menuButton');
  const menu = document.querySelector('#accountMenu');

  button.addEventListener('click', () => {
    const open = button.getAttribute('aria-expanded') === 'true';
    button.setAttribute('aria-expanded', String(!open));
    menu.hidden = open;
  });
</script>

More Practice Examples

Example 1: Button with live status

<button id="saveButton" type="button">Save profile</button>
<p id="saveStatus" role="status"></p>

<script>
  const button = document.querySelector('#saveButton');
  const status = document.querySelector('#saveStatus');

  button.addEventListener('click', () => {
    status.textContent = 'Profile saved successfully.';
  });
</script>
  • The button has visible text, so it already has an accessible name.
  • role="status" announces the result without moving focus.
  • The message is useful because it confirms that the action worked.

Example 2: Form field with hint and error

<label for="username">Username</label>
<input id="username" name="username" aria-describedby="usernameHint usernameError" aria-invalid="true">
<p id="usernameHint">Use 4 to 20 letters or numbers.</p>
<p id="usernameError">Username is required.</p>
  • The label gives the input its accessible name.
  • aria-describedby connects both the hint and current error.
  • aria-invalid tells assistive technology the current value needs correction.

Example 3: Visible focus and reduced motion

.action:focus-visible {
  outline: 3px solid #2563eb;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .action {
    transition: none;
  }
}
  • focus-visible keeps keyboard focus obvious without showing rings for every mouse click.
  • outline-offset separates the focus indicator from the element edge.
  • The reduced motion query keeps interaction calm for people who request it.

Example Explained

  • The ARIA Roles & Attributes example starts with semantic HTML so the browser provides as much accessibility behavior as possible.
  • Labels, text, headings, landmarks, and descriptions create the information assistive technology needs.
  • ARIA is used only when it adds a missing relationship, state, or announcement.
  • Keyboard behavior is part of the feature, not an optional extra.
  • The example can be tested by completing a real task, not only by inspecting code.

How to Read This Example

  1. Find the interactive elements first: links, buttons, form fields, dialogs, menus, or custom widgets.
  2. Name each control out loud and check whether the visible text, label, aria-label, or aria-labelledby provides that name.
  3. Check role and state next, such as expanded, invalid, selected, pressed, checked, or hidden.
  4. Tab through the example and confirm the focus order follows the visual and logical task order.
  5. Change one part of the ARIA Roles & Attributes example, then retest with keyboard and automated checks.

Code Editor Example

Open a ready-made starter for this lesson in the live HTML, CSS, and JavaScript editor. You can change the code, then click Run to see the result immediately.

Open in Code Editor

Checklist

  • Test with keyboard only before relying on automated tools.
  • Use visible labels, focus states, and clear error messages.
  • Prefer semantic HTML and add ARIA only when it adds real meaning.

Common Mistakes

  • Treating automated audit scores as the whole accessibility test.
  • Removing focus outlines without replacing them.
  • Using ARIA to patch invalid or non-semantic HTML instead of fixing the HTML.

Do and Don't

  • Do: begin ARIA Roles & Attributes with real HTML elements, visible labels, and clear content.
  • Do: keep focus indicators visible and test every interactive element with the keyboard.
  • Do: connect helper text, errors, and dynamic status messages programmatically.
  • Don't: use ARIA to hide invalid markup or avoid native controls.
  • Don't: depend only on color, icon shape, placeholder text, animation, or mouse hover.

Practice Challenge

Test the ARIA Roles & Attributes pattern using only Tab, Shift+Tab, Enter, Space, and Escape, then check whether names and states are announced clearly.

Try These Changes

  • Remove the visible label from one control, run the editor, then restore the label and compare the result.
  • Add a validation error and connect it with aria-describedby and aria-invalid.
  • Use only Tab, Shift+Tab, Enter, Space, and Escape to complete the example task.
  • Change a button or link color and check whether the focus, hover, and active states still remain readable.
  • Add one dynamic success message and decide whether it should move focus or use a live region.

Quick Check

  • Question: Should ARIA be the first solution? Answer: No, use semantic HTML first and ARIA only when it adds needed meaning.
  • Question: What should every control have? Answer: An accessible name and a visible or understandable purpose.
  • Question: What catches focus order problems? Answer: Manual keyboard testing with Tab and Shift+Tab.
  • Question: Can automated tools prove a page is accessible? Answer: No, they catch many code issues but not every human task issue.
  • Question: What is a good first manual test? Answer: Complete the main task without using a mouse.

Debugging Checks

  • Inspect the accessibility tree or browser accessibility panel to confirm names, roles, and states.
  • Check whether hidden content is hidden from everyone or only visually hidden.
  • Look for div or span elements that act like buttons, links, tabs, or menus without keyboard behavior.
  • Confirm focus is visible, logical, and restored after dialogs, menus, validation, or route changes.
  • Run automated checks after manual testing so code-level issues are not missed.

Mini Project

Build an accordion for ARIA Roles & Attributes: real buttons, aria-expanded, aria-controls, hidden panels, keyboard support, and clear headings.

Mastery Check

  • You can test the ARIA Roles & Attributes pattern without a mouse.
  • You can identify the accessible name and state of each control.
  • You can explain which checks require manual testing.
Create a free account to save which lessons you've finished. Save my progress