AccessibilityTYPENORMLabs7 minJuly 23, 2026

ARIA Labels — A Practical Accessibility Guide

An ARIA label gives a control an accessible name a screen reader can announce. When you actually need one, how aria-label differs from aria-labelledby, and the mistakes that make things worse.

An ARIA label is a short piece of text that gives a control its accessible name — the words a screen reader announces when it lands on that element. You add it with the aria-label attribute (or aria-labelledby), and it exists for one reason: so a button, link, or input that has no visible text still tells assistive tech what it does. A magnifying-glass icon that any sighted user reads as "search" is, to a screen reader, a button with no name at all. An ARIA label is how you hand that name back.

It's also one of the most over-used tools in accessibility. Teams reach for aria-label reflexively, paste it onto elements that already have a name, and end up making the experience worse. This guide covers what an ARIA label actually does, when you genuinely need one, the difference between aria-label and aria-labelledby, and the mistakes that turn a good intention into a broken announcement. It's part of the broader practice of web accessibility — the labeling layer specifically, where a control's name gets decided.

What an ARIA label actually does

Every interactive element on a page has an accessible name, computed by the browser from a defined order of sources. For a <button>Save</button>, the name is its text: "Save." For an <input> wired to a <label>, it's the label text. The screen reader reads that name so a user who can't see the screen knows what they're about to activate.

An ARIA label overrides that computation. aria-label="Save" sets the accessible name directly, ignoring whatever text might be inside the element. That power is exactly why it's dangerous: it's a manual override of an automatic system that usually gets it right on its own. Use it where the automatic name is missing or wrong, and nowhere else.

The single most useful rule here comes straight from the spec authors: no ARIA is better than bad ARIA. A missing label is a problem; a wrong or duplicated label is often a bigger one, because it actively misleads the person relying on it.

The first rule: prefer a visible label

Before you add an ARIA label, check whether you need one at all. The first rule of ARIA use is that if a native HTML element or attribute already gives you the semantics and behavior you want, use it instead of repurposing something with ARIA.

For naming, that means a visible text label beats an ARIA label almost every time. Visible text helps everyone. Sighted users, screen-reader users, people under cognitive load, voice-control users who literally say "click Search." An aria-label is invisible: it helps only the assistive-tech user, and it drifts out of sync with the interface because nobody looking at the screen ever sees it to catch the mistake. Reach for an ARIA label when a visible one genuinely isn't possible, like an icon-only button or a landmark that needs distinguishing. Not as the default way to name things.

aria-label vs aria-labelledby vs aria-describedby

Three attributes get confused constantly. They do different jobs:

  • aria-label — you type the name directly as a string: aria-label="Close dialog". Best for short, icon-only controls where no suitable text exists anywhere on the page.
  • aria-labelledby — you point at the id of visible text elsewhere on the page, and that text becomes the name: aria-labelledby="dialog-title". Prefer this whenever the name already exists on screen — it stays in sync, gets translated with the page, and keeps one source of truth.
  • aria-describedby — points at supplementary text read after the name, for hints and help ("Password must be at least 8 characters"). It's a description, not a name; it never replaces the label.

The order of precedence matters: aria-labelledby wins over aria-label, which wins over the element's own text or associated <label>. If you set two, the more powerful one silently overrides the other. That's a common source of "why is it reading the wrong thing" bugs.

When you actually need an ARIA label

There's a short list of situations where an ARIA label earns its place:

  • Icon-only controls. A button that's just an icon — hamburger menu, close ✕, search magnifier, kebab overflow — has no text node, so its accessible name is empty. aria-label="Menu" fixes it. This is the canonical, correct use of an ARIA label.
  • Distinguishing repeated landmarks. Two <nav> elements on one page both announce as "navigation." Add aria-label="Primary" and aria-label="Footer" so a screen-reader user can tell them apart in the landmarks list.
  • Inputs that can't have a visible <label>. A search field in a compact header, where design won't allow visible label text, needs aria-label="Search" so it isn't announced as an anonymous edit field. (A visually-hidden real <label> is often the better fix — but an ARIA label is a legitimate fallback.)
  • Links whose text repeats. A list of "Read more" links all read identically out of context. aria-label="Read more about ARIA labels" gives each one a unique, meaningful name.

Every one of these is the same shape: the visible interface works fine for sighted users but leaves the accessible name empty or ambiguous. That gap is the only thing an ARIA label should fill.

Common ARIA label mistakes

Most ARIA label failures come from a small set of avoidable errors:

Labeling an element that already has a name

Putting aria-label="Save" on <button>Save</button> is redundant at best. Worse, when the two disagree — aria-label="Submit" on a button that visibly reads "Save" — the screen reader announces "Submit" while the sighted user sees "Save," and voice-control users who say "click Save" hit nothing. Don't override a name that's already correct.

Putting aria-label on elements that don't take a name

aria-label only works reliably on interactive elements and roles that support naming — buttons, links, inputs, landmarks. Slap it on a plain <div> or <span> with no role and many screen readers ignore it entirely. If an element needs a name, it usually needs a role first.

Forgetting that aria-label replaces, not adds

An ARIA label doesn't append to the visible text — it replaces the accessible name wholesale. <button aria-label="Delete">Trash</button> is announced as "Delete," and the visible word "Trash" is lost to assistive tech. If both matter, the visible text should carry the name and the ARIA label shouldn't be there.

Writing labels a machine has to decode

The label is spoken aloud, so write it like speech. "Close" beats "btn-close-modal-x." Skip redundant role words. A screen reader already says "button," so aria-label="Search button" announces "Search button, button." Name the action, let ARIA supply the role.

ARIA labels and screen readers

A label only counts once you've heard it. The name you type isn't always what gets announced: the browser and screen reader compute the final accessible name together, and edge cases surface only in a real reader. So test with one: VoiceOver on macOS and iOS (built in), NVDA on Windows (free), or TalkBack on Android. Tab to each control and listen to what it says.

You're checking three things: every interactive element announces a name, the name matches what the control actually does, and nothing double-announces ("Search search button"). A browser's accessibility inspector shows the computed name without a screen reader for a fast first pass, but it can't tell you whether the name makes sense out loud. Only listening does.

ARIA labels are one slice of accessibility, not the whole of it. A perfectly-named button still fails a user if its text is unreadable against its background. That's a separate problem, and you can catch it with our free contrast checker. Both are cheap if you catch them while building, brutal if you find them the week before launch. Same lesson, different attribute.

FAQ

What is an ARIA label? An ARIA label is text set with the aria-label attribute that gives an element its accessible name — the words a screen reader announces for it. It's used mainly for controls with no visible text, like icon-only buttons, so assistive tech can tell the user what the control does.

When should I use aria-label vs a visible label? Prefer a visible text label almost every time — it helps sighted users, voice-control users, and screen-reader users alike, and it can't silently drift out of date. Use aria-label only when a visible label genuinely isn't possible, such as an icon-only button or distinguishing two identical landmarks.

What's the difference between aria-label and aria-labelledby? With aria-label you type the name directly as a string. With aria-labelledby you reference the id of visible text already on the page, and that text becomes the name. Prefer aria-labelledby when the name exists on screen, because it stays in sync and gets translated with the page. When both are present, aria-labelledby wins.

Does aria-label work on any HTML element? No. It's reliable on interactive elements and elements with a role that supports naming — buttons, links, inputs, landmarks. On a plain <div> or <span> with no role, screen readers often ignore it. If an element needs a name, give it a role first.

Is aria-label the same as alt text? No. alt text describes an image; aria-label names an interactive control. They overlap only when an image is the control — an icon acting as a button — and even then it's cleaner to label the button than the image inside it.

The one question to ask

Before you add an ARIA label, one question: could a visible name do this job instead? Usually it can, and then it should — visible text is the more honest fix, and the one that survives a redesign. That's most of the discipline right there. Where a visible name truly can't exist, one short aria-label turns a silent control into one that announces itself. Everywhere else it's an override no one can see, quietly telling a screen reader the wrong thing.

Free UX Snapshot for 50 Product Teams

Apply now and get a complimentary UX Snapshot — our rapid clarity audit delivered in 48 hours. Limited to the first 50 products.

Apply for Free UX Snapshot

Related

Navigation Design

Zara UX Teardown: The Homepage That Doesn't Scroll

A UX teardown of Zara's public store: a homepage one screen tall, navigation reduced to grey hairlines, and a catalog that won't quote a price until you type into the search box.

TYPENORMLabs · 7 min · August 16, 2026

Ecommerce
Web
Navigation Design

Interaction Design

Whimsical UX Teardown: Free Until You Share It

A UX teardown of Whimsical's product pages: a whiteboard that sells speed by removing the blank canvas, and a free plan that gives away unlimited private boards while capping shared ones at three.

TYPENORMLabs · 6 min · August 6, 2026

Productivity
Web
Interaction Design

Research Methods

Writing Closed Questions in Research: Getting Answers You Can Count

A closed question fixes the answer set before anyone reads it, which is what makes it countable and what makes it fragile. The forms, the five ways the wording breaks, and how to pretest before you send.

TYPENORMLabs · 9 min · August 15, 2026

Research Methods
UX Writing
Web