skip to content

In HTML and ARIA, what is an element's accessible name, and what does the browser compute it from for `<button>Save</button>` and `<img src="logo.png" alt="Acme home">`?

level: juniorimportance: must knowfreq 60%

answer

  1. what the screen reader says out loud
  2. not a single attribute — a computation
  3. each element type has its own source
  4. button text, img alt, table caption
  5. empty name means bare "button"

basics

~20 s

An element's accessible name is the short label assistive technology announces for it. The browser computes it per element type: a button's name comes from its own text content, an image's from its alt attribute.

solid answer

~50 s

The accessible name is the string a screen reader or voice-control tool announces to identify an element — it is what the user hears alongside the role, as in "Save, button". It is **computed**, not stored in one attribute: the browser runs the accessible name computation and takes the first source that yields text. For `<button>Save</button>` the source is the element's own text content, so the name is "Save". For `<img src="logo.png" alt="Acme home">` the source is `alt`, so the name is "Acme home". Different elements have different native sources: a `<table>` takes its name from `<caption>`, a `<fieldset>` from `<legend>`, a `<figure>` from `<figcaption>`, and a form control from its associated `<label>`. An interactive control with no name at all is announced as bare "button" or "edit text", which leaves the user with no idea what it does.

go deeper

for a junior

Be able to say that the accessible name is what a screen reader announces to identify an element, and name the obvious sources: a button's text, an image's alt, a form field's label.

for a middle

Explain that the name is computed by an algorithm over an ordered list of sources rather than read from one attribute, and map the native source for buttons, images, tables, fieldsets and form controls.

for a senior

Show that you verify names against the accessibility tree in DevTools rather than inferring them from markup, and that you catch nameless controls in review and in automated role-plus-name test queries.

for a principal

Own the guarantee at the system level: pick component APIs that make a missing accessible name impossible to ship, and put a name assertion into the shared test and lint tooling so the property is enforced rather than remembered.

## What an accessible name actually is Every element exposed to assistive technology sits in the **accessibility tree** — a parallel tree the browser builds from the DOM, where each node carries a small set of properties: a **role** (what kind of thing it is), a **name** (which one it is), sometimes a **value** and a **state**, and optionally a **description**. The accessible name is the identity string. A screen reader typically announces name plus role — "Save, button", "Search, edit text", "Acme home, link". Voice-control software matches spoken commands against the same string: "click Save" works because the button's accessible name is "Save". Automated tooling uses it too — queries like `getByRole('button', { name: 'Save' })` in Testing Library and Playwright match on the computed accessible name, not on the raw markup. The key word is **computed**. There is no single `name` attribute in HTML. The browser follows the accessible name computation, a specified algorithm shared by HTML and ARIA, and walks a list of candidate sources in order until one produces a non-empty string. ## Where the name comes from, element by element Each element type has its own native source, defined by the HTML Accessibility API Mappings: ```html <button>Save</button> <!-- name: "Save" (text content) --> <a href="/help">Help centre</a> <!-- name: "Help centre" (text content) --> <img src="logo.png" alt="Acme home"> <!-- name: "Acme home" (alt) --> <label for="q">Search</label> <input id="q" type="search"> <!-- name: "Search" (associated label) --> <table><caption>Q3 revenue</caption>…</table> <!-- name: "Q3 revenue" (caption) --> <fieldset><legend>Shipping</legend>…</fieldset> <!-- name: "Shipping" (legend) --> <figure><img …><figcaption>Fig 1</figcaption></figure> <!-- name: "Fig 1" (figcaption) --> ``` Notice the pattern: elements whose visible content *is* the label (buttons, links, headings) take their name from their **subtree text**, while elements whose content is not a label (images, tables, groups, form fields) take it from a dedicated attribute or a companion element. This is the practical reason to reach for the right native element. `<button>Save</button>` gets a role, keyboard activation, focusability and a name from one element with no extra attributes. A `<div>` with a click handler gets none of them and must have all four reproduced by hand. ## alt="" is a deliberate empty name `<img alt="">` is not a missing alt. An empty `alt` tells the browser the image carries no information the user needs, and the image is removed from the accessibility tree entirely — a screen reader passes over it silently. That is the correct markup for a decorative divider or a background flourish. Omitting `alt` altogether is a different thing: with no `alt` there is no name source, so assistive technology may fall back to announcing the file name from `src`, which is why users hear "logo dot png, image". Every `<img>` needs an `alt` attribute; the judgement is only whether its value is empty or descriptive. ## Controls with no name The common failure is an interactive control that computes to an empty name: ```html <button><svg viewBox="0 0 16 16"><path d="…"/></svg></button> ``` The subtree contains an SVG with no text, so the computed name is empty and the control is announced as just "button". The user can reach it and press it but cannot tell what it does, and a voice-control user has no phrase to say. The same happens with an input whose only visible hint is a `placeholder`, since `placeholder` is at best a last-resort fallback and disappears the moment the user types. ## How to check it Do not guess from the markup — read the computed value. Chrome DevTools shows it in the **Accessibility** pane of the Elements panel, including which source produced it; Firefox has an Accessibility Inspector that shows the same tree. Automated scanners such as axe report controls whose accessible name is empty as a violation, and a `getByRole(…, { name })` query in a test suite fails loudly when a refactor silently strips the name. The habit worth forming is to treat the accessible name as a real, inspectable output of your markup, the same way you treat computed styles — something you verify rather than assume.

  • Why is `<img alt="">` acceptable but omitting the alt attribute entirely is not?
    `alt=""` is an explicit statement that the image is decorative: the browser removes it from the accessibility tree and a screen reader skips it silently. With no `alt` at all there is no name source, so assistive technology often falls back to announcing the file name from `src` — users hear "logo dot png, image". Every `<img>` needs the attribute; only its value is a judgement call.
  • An icon-only `<button>` containing just an inline SVG is announced as "button" with nothing else. Why?
    The button's native name source is its subtree text, and an SVG shape contributes no text, so the computation yields an empty string. The element still has a role and is focusable, so the user can press it but has no idea what it does, and voice control has no phrase to match. The control needs a name from some source before it is usable.
  • How does the accessible name differ from the role?
    The role says what kind of thing an element is — button, link, checkbox, table — and comes from the element itself or an explicit `role` attribute. The name says which particular one it is. Screen readers announce them together, as in "Save, button", and both must be present for the control to be usable: a nameless button and an unlabelled role are equally opaque.

saying these in an interview costs you the question

  • Thinks every element needs aria-label to have a name
  • Says the accessible name is always just the visible text
  • Confuses the accessible name with the element's role
  • Treats alt="" as a mistake rather than a decorative marker
  • Believes a placeholder counts as a proper label

context