Lesson 4 of 30
Every interactive element needs an accessible name, a role, and sometimes a state — and the most common real-world bug is an icon-only control that quietly has none of the first.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A `<button>` contains only an SVG icon marked `aria-hidden="true"`, with no other text and no `aria-label`. What does a screen reader announce for it?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Every interactive element's accessibility-tree node is built from a small, consistent set of parts:
aria-labelledby (points at another element's text) first, then aria-label (a literal string), then an associated <label>, then the element's own visible text content, and title as a last resort that shouldn't be relied on as a primary source.<button> is role "button", <a href> is role "link"). When there's no native equivalent, role="..." sets it explicitly.aria-checked, aria-expanded, aria-pressed kept in sync with actual component state by hand.Together this is often shortened to "name, role, value" — and it's the same idea WCAG's success criterion 4.1.2 is checking for. A control missing any of the three is incomplete to assistive technology even if it's fully functional for a mouse user.
<!-- Broken: visually clear, completely silent to a screen reader -->
<button onclick="deleteItem()">
<svg aria-hidden="true"><!-- trash can icon --></svg>
</button>
A sighted user recognizes the trash-can icon instantly. A screen reader user gets nothing — the button has a role ("button," from the native element) but no name, because its only content is an SVG that's correctly marked aria-hidden (a decorative icon shouldn't be independently announced) and there's no text left to compute a name from. The result: "button" with no label, which is functionally useless. The fix is one attribute:
<!-- Fixed: aria-label supplies the name text content doesn't provide -->
<button onclick="deleteItem()" aria-label="Delete item">
<svg aria-hidden="true"><!-- trash can icon --></svg>
</button>
This is the single most common real-world instance of a missing accessible name — any icon-only control (close buttons, menu toggles, social icons, pagination arrows) needs an explicit name, because there's no visible text for the browser to fall back to.
aria-label has a role but no name — and a role alone is not enough. "Button" with nothing else announced tells a screen reader user something is there and interactive, but not what it does, which is close to useless for taking action confidently.aria-label overrides visible text entirely, including for sighted screen-reader users following along visually — mismatches between the two are a real bug. If a button visibly says "Learn more" but has aria-label="Click here", a screen reader announces "Click here" while a sighted user reads "Learn more" — the label should describe the same thing the visible text does, just adapted for context if needed (e.g. "Learn more about pricing" when several "Learn more" links exist on one page).aria-describedby supplements the name; it doesn't replace it. Pointing aria-describedby at a hint or error message adds it as extra announced context after the name — it's not a way to give a nameless element a name."Here's an icon-only button with no visible text — what's wrong with it, and how do you fix it?" is a genuinely common practical question, and the strong answer names the accessible-name computation order directly (why aria-hidden on the icon is correct, and why aria-label on the button itself is the actual fix) rather than a vague "add some ARIA to it."