Buttons need a name
- Rule:
axe/button-name - Checks: Buttons must have discernible text
- WCAG: 4.1.2
- Fix class:
content: A fix needs authored text.
Who it affects
Section titled “Who it affects”- People who use a screen reader or a braille display, most of them blind.
- People who control the page by speaking.
How to fix it
Section titled “How to fix it”The button shows only an icon
Section titled “The button shows only an icon”Name the button for its action with aria-label, and hide the icon from assistive technology with aria-hidden="true".
<button type="button" aria-label="Close"> <svg aria-hidden="true" focusable="false"><use href="#icon-close"></use></svg></button>The icon is an <img>
Section titled “The icon is an <img>”Give the image an alt that names the button’s action. The button takes its name from the image’s text alternative.
<button type="button"><img src="search.svg" alt="Search"></button>The button holds its text in a hidden element or draws it with CSS
Section titled “The button holds its text in a hidden element or draws it with CSS”Put the words inside the button as text. To hide them visually, use a class that clips them but keeps them in the accessibility tree; display: none and visibility: hidden remove them from it. axe ignores text drawn with CSS content, and assistive technology does not announce it reliably.
<button type="button"> <svg aria-hidden="true" focusable="false"><use href="#icon-trash"></use></svg> <span class="visually-hidden">Delete order</span></button>Visible text elsewhere on the page already names the action
Section titled “Visible text elsewhere on the page already names the action”Point aria-labelledby at that text by its id, so the name and the visible words stay the same.
Fixes that fail
Section titled “Fixes that fail”Adding only a title attribute
Section titled “Adding only a title attribute”axe accepts it and screen readers announce it, but it shows only while a mouse hovers, so keyboard, touch and voice control users never see the name.
Naming the icon rather than the action, such as aria-label="X" or aria-label="Magnifying glass"
Section titled “Naming the icon rather than the action, such as aria-label="X" or aria-label="Magnifying glass"”People hear what the button looks like, not what it does. Name the action: “Close”, “Search”.
Adding aria-hidden="true" to the button
Section titled “Adding aria-hidden="true" to the button”It takes the button out of the rule by hiding it from assistive technology, but the button stays focusable, so keyboard and screen reader users still reach a control nothing announces. axe then reports it under aria-hidden-focus.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
An icon button component does not pass aria-label to its <button>
Section titled “An icon button component does not pass aria-label to its <button>”Take the name as a required prop and set it on the <button> after spreading the other props, so nothing in the spread can replace it.
function IconButton({ icon: Icon, label, ...rest }) { return ( <button type="button" {...rest} aria-label={label}> <Icon aria-hidden="true" focusable="false" /> </button> );}Fixes that fail in React
Section titled “Fixes that fail in React”Passing aria-label to a component that does not forward it
Section titled “Passing aria-label to a component that does not forward it”The prop never reaches the DOM, so the button stays unnamed. Check the rendered HTML, not the JSX.
More on the rule
Section titled “More on the rule”axe-core’s documentation of the rule
CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.