Custom buttons, links and menu items need a name
- Rule:
axe/aria-command-name - Checks: ARIA commands must have an accessible name
- 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 control shows only an icon
Section titled “The control shows only an icon”Name the control for its action with aria-label, and hide the icon from assistive technology with aria-hidden="true". Where a native <button> or <a href> fits, use it instead of the role: it brings keyboard support and focus with it.
<div role="button" tabindex="0" aria-label="Close"> <svg aria-hidden="true" focusable="false"><use href="#icon-close"></use></svg></div>The words are in a hidden element or drawn with CSS
Section titled “The words are in a hidden element or drawn with CSS”Put the words inside the control as text, hidden visually if need be with a class that clips them but keeps them in the accessibility tree; text inside display: none, visibility: hidden or aria-hidden="true" does not count. axe also ignores text drawn with CSS content. An icon font character written into the markup passes axe but reads as nothing or a stray symbol, so it does not name the control.
<div role="menu" aria-label="Order actions"> <div role="menuitem" tabindex="-1"> <svg aria-hidden="true" focusable="false"><use href="#icon-trash"></use></svg> <span class="visually-hidden">Delete order</span> </div></div>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, but it shows only while a mouse hovers, so keyboard, touch and voice control users never see what to call the control.
Describing the icon rather than the action, such as aria-label="Arrow"
Section titled “Describing the icon rather than the action, such as aria-label="Arrow"”People hear what the control looks like, not what it does. Name the result: “Next page”, “Close”.
Removing the role to silence the rule
Section titled “Removing the role to silence the rule”The rule stops matching, but the element still reacts to clicks and now has no role or name for assistive technology at all.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
A menu item or custom button component drops the aria-label its caller passes
Section titled “A menu item or custom button component drops the aria-label its caller passes”Spread the props the component does not use onto the element that has the role, so a caller’s aria-label or aria-labelledby reaches the DOM.
function MenuItem({ icon, ...props }) { return ( <li role="menuitem" tabIndex={-1} {...props}> <svg aria-hidden="true" focusable="false"> <use href={`#icon-${icon}`} /> </svg> </li> );}
function OrderMenu() { return ( <ul role="menu" aria-label="Order actions"> <MenuItem icon="trash" aria-label="Delete order" /> </ul> );}Fixes that fail in React
Section titled “Fixes that fail in React”Adding aria-label where the component is used, when the component does not pass it on
Section titled “Adding aria-label where the component is used, when the component does not pass it on”The prop stops at the component, so the rendered element still has no name. Check the rendered DOM, not the JSX.
Writing the prop in camel case, as ariaLabel
Section titled “Writing the prop in camel case, as ariaLabel”React renders it as an unknown arialabel attribute, which names nothing. ARIA attributes keep their hyphens in JSX: aria-label.
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.