Skip to lesson content
WCAG 4.1.2 · Level AEasy5 min readARIA

Missing ARIA Labels on Interactive Elements

Overview

Interactive elements (buttons, inputs, landmarks) must have an accessible name so assistive technology can announce what they do.

ARIA labels give assistive technology an “accessible name”—the text a screen reader announces for a control. Icon-only buttons (a bare hamburger, a trash can, a magnifying glass) are the classic offender: visually obvious, but announced as just “button.” The first rule of ARIA is to use native HTML where possible, but when you build custom controls or icon buttons, a correct aria-label (WCAG 4.1.2) is what makes them usable.

WCAG Criterion:4.1.2
Conformance Level:Level A
Difficulty:Easy
Time to fix:~5 min
Category:ARIA

The Problem

This pattern is inaccessible — avoid it.

[ AVOID ]
<button><svg>...</svg></button> <!-- icon-only, no label --> <div role="dialog">...</div> <!-- no dialog title --> <nav>...</nav> <!-- multiple navs, no differentiation -->

The Fix

Use this accessible pattern instead.

[ CORRECT ]
<button aria-label="Close dialog"><svg aria-hidden="true">...</svg></button> <div role="dialog" aria-labelledby="dialog-title"> <h2 id="dialog-title">Confirm deletion</h2> </div> <nav aria-label="Main navigation">...</nav> <nav aria-label="Breadcrumb">...</nav>

Step-by-step

  1. Every icon-only button must have aria-label or aria-labelledby.

  2. Dialogs/modals need aria-labelledby pointing to the visible heading.

  3. When there are multiple <nav> landmarks, give each an aria-label.

  4. Add aria-hidden="true" to decorative SVGs/icons so screen readers skip them.

Common Mistakes

  • Icon-only buttons or links with no aria-label.

  • Decorative SVGs left without aria-hidden="true", cluttering the screen reader.

  • Multiple <nav> or <section> landmarks with no distinguishing label.

  • Overriding a visible label with a different aria-label, which confuses voice-control users.

How to Test for It

  • Tab to each icon button in a screen reader and confirm it announces a clear name.

  • Inspect the accessibility tree in DevTools—every control should have a non-empty name.

  • Run an automated scan for controls missing an accessible name.

Framework Notes

How to apply this fix in your stack.

[ REACT ]
// Icon button pattern <button aria-label="Delete item"> <TrashIcon aria-hidden="true" /> </button>

FAQ