( Robust / WCAG 4.1.2 )
Interactive element has no accessible name at all
What is this issue?
An interactive element has no accessible name through any recognized source at all: no visible text content, no alt attribute on an inner image, no aria-label, no aria-labelledby, and no <label> connection. It comes from the first source that applies, in order: aria-labelledby, aria-label, visible label text, then other fallbacks specific to the element type; here, none of them resolve to anything.
This differs from the role-specific naming rules in this cluster, which each inspect one recognized ARIA role (button, textbox, switch, and so on) and check whether that role’s naming sources are empty. This rule catches elements that don’t fit neatly into any of those categories: unusual custom markup, an interactive-behaving element with no role at all, or a component so heavily customized that a deterministic per-role check can’t reliably classify it.
Why does this matter?
Every other rule in this cluster describes a widget that’s at least partially exposed: its role announces, just not its purpose. This rule catches the cases where nothing reaches assistive technology at all: no role, no name, sometimes not even keyboard reachability, because the element was built entirely outside the semantics HTML and ARIA both provide for free.
That combination, genuinely zero information plus, often, no keyboard access, is why this failure carries a critical rather than serious impact rating elsewhere in this cluster. A screen reader user doesn’t just lose context about what a control does; in the worst cases, they don’t know the control exists on the page at all.
Who is affected?
- Screen reader users: encounter nothing at all where an interactive control should be, or a generic, silent stop in the tab order with no announcement of any kind.
- Voice control users: have no accessible name to speak as a command, so a control with genuinely no name can’t be activated by voice under any phrasing, unlike a poorly-named control that might still coincidentally match visible text nearby.
- Cognitive disabilities: lose any way to build a mental model of what’s interactive on the page when a control’s presence is entirely unannounced, making the page feel less predictable and harder to navigate reliably.
What users experience
Femi uses NVDA on Windows to browse a news site on his laptop. The site’s mobile-style navigation menu button, present even on desktop, is built as a <span class="menu-icon" onclick="toggleNav()"> with three CSS-drawn bars and nothing else: no role, no tabindex, no text, no aria-label. Tabbing through the header, NVDA skips straight past it in total silence, since the element isn’t even keyboard-focusable, let alone named. Femi never discovers the site has a navigation menu at all and gives up trying to find the sections he was looking for.
How do I fix it?
Start by making the element genuinely operable before naming it, since a control with no name is often also missing basic interactive behavior: add role="button" (or switch to a native <button>) and tabindex="0" with keyboard handling if the element isn’t already reachable by Tab and activatable with Enter/Space. This works because a name with no way to reach the element by keyboard still leaves keyboard-only users locked out entirely.
Then add whichever naming source fits the element: visible text is simplest and needs no ARIA at all; aria-label works well for icon-only controls with no room for visible text; a connected <label> fits any form-shaped control; and alt on an inner image works when the image alone conveys the control’s purpose.
Where possible, replace the custom element with the native equivalent it’s imitating: a real <button> instead of a <span> with a click handler, or a real <a href> instead of a <div> styled as a link. Native elements come with keyboard behavior, a role, and (once given text) a name, all without hand-wiring any of the three separately.
Code Examples
<span class="menu-icon" onclick="toggleNav()">
<i class="bar"></i><i class="bar"></i><i class="bar"></i>
</span><!-- Method 1: native button (preferred, gets role and keyboard for free) -->
<button class="menu-icon" aria-label="Open navigation menu" onclick="toggleNav()">
<i class="bar" aria-hidden="true"></i><i class="bar" aria-hidden="true"></i><i class="bar" aria-hidden="true"></i>
</button>
<!-- Method 2: role + tabindex kept, added by hand -->
<span
class="menu-icon"
role="button"
tabindex="0"
aria-label="Open navigation menu"
onclick="toggleNav()"
onkeydown="if(event.key==='Enter'||event.key===' ')toggleNav()"
>
<i class="bar" aria-hidden="true"></i><i class="bar" aria-hidden="true"></i><i class="bar" aria-hidden="true"></i>
</span>Method 1 replaces the span with a native <button>, which restores keyboard focus and activation automatically and only needs aria-label added on top. Method 2 keeps the original element but rebuilds every piece of missing behavior by hand: the role, the keyboard focus, the Enter/Space activation, and the name, which is considerably more code to maintain than switching to native markup in the first place.
Framework Examples
A shared icon-only button component from a design system or component library is a common source of this rule’s most severe failures, since a single unlabelled component definition can ship dozens of nameless, sometimes unfocusable controls across a whole product. Require a name at the component’s interface level so a missing label fails during development, not during an audit.
function IconButton({ icon, label, onClick }) {
return (
<button aria-label={label} onClick={onClick}>
<span aria-hidden="true">{icon}</span>
</button>
);
}
// TypeScript: label: string (required, not optional) turns a
// forgotten name into a compile-time error across every call site.
Using a native <button> inside the component also closes the keyboard-access gap this rule frequently catches alongside the missing name; a <span onClick> reimplementation loses both problems at once, while a <button>-based component avoids them structurally.
Common Mistakes
Mistake: “It’s just a visual icon, so accessibility rules for text controls don’t apply to it.” Any element that responds to a click and changes what the user sees or does next is functionally a control, regardless of what tag or styling it uses. If it behaves like a button, it needs the naming, role, and keyboard treatment a button needs; the visual design choice doesn’t exempt it.
Mistake: “RedFlag’s Review Labels feature has to be turned on before this counts as a real bug.” The underlying accessibility failure exists in the markup whether or not RedFlag’s AI-assisted review surfaces it; the detection method affects how RedFlag reports the issue, not whether it’s genuinely broken for a screen reader user encountering it today.
Mistake: “I added tabindex="0", so the element is now accessible.” tabindex="0" only makes an element reachable by keyboard. It supplies no role and no name on its own; a focusable, unlabelled span is a strict improvement over an unfocusable one, but it’s still a keyboard trap of confusion: the user reaches it and hears nothing describing what it is.
How RedFlag Detects This
AI-assisted: flagged by the optional Review Labels feature. RedFlag’s Review Labels workflow surfaces candidate elements it suspects have no usable accessible name from any source, drawing on signals a single deterministic rule can’t reliably combine across arbitrary custom markup: interactive-looking behavior, absent role, and absent naming attributes together. A human reviewer then confirms, edits, or rejects each candidate before it’s recorded as a violation; nothing here is auto-graded the way a fixed DOM query is.
False negative: if Review Labels isn’t enabled, or a reviewer hasn’t yet worked through the queue, a genuinely nameless element ships with no recorded violation at all; detection depends on the feature being active and reviewed, not on a scan that always runs. False positive: a candidate can be surfaced for an element that’s intentionally non-interactive decoration with an onclick left over from earlier code, which a reviewer should reject rather than confirm. Manual step: treat this rule’s coverage as a supplement to, not a replacement for, a manual keyboard-and-screen-reader pass across custom components, since the AI-assisted flag depends on a human working through the review queue.
Manual Testing
- Open the page in Chrome or Firefox with NVDA, JAWS, or VoiceOver running.
- Tab through the entire page from the top, noting any point where focus visibly skips past something that looks interactive on screen (an icon, a custom control) with no announcement.
- For anything that responds to a click but wasn’t reached by Tab, confirm whether it’s genuinely meant to be interactive; if so, it’s failing this rule on keyboard access as well as naming.
- For anything that is reached by Tab, listen for a role and a name together (“Open navigation menu, button”) rather than silence or a bare, generic role.
- Repeat the same pass on a second screen reader/browser combination, since custom markup with no semantics often behaves inconsistently across assistive technology in ways a role-based element wouldn’t.
Related WCAG Success Criteria
4.1.2 Name, Role, Value: Every interface component must expose a name, role, and current value to assistive technology. This rule catches the most complete failure of that requirement: an element with none of the three reliably exposed, rather than one missing piece.
2.1.1 Keyboard: All functionality must be operable through a keyboard interface. Elements this rule catches frequently fail 2.1.1 at the same time as 4.1.2, since custom interactive markup with no accessible name often also has no tabindex or keyboard event handling at all.
Related Issues
ARIA command has no accessible name covers the same underlying gap on elements that at least carry a recognized command role: a narrower, fully automated version of the failure this rule catches more broadly.
ARIA input field has no accessible name and ARIA toggle field has no accessible name cover the same missing-name problem on elements with a recognized data-entry or toggle role, again with a deterministic automated check this rule’s broader net doesn’t rely on.
Button or link has no accessible name is the native-HTML, fully automated equivalent for real <button> and <a> elements specifically.
Link text is generic and gives no context covers a related but distinct failure: a link that has a name, just not a useful one, worth checking alongside any link this rule flags as having no name at all.
References
Frequently asked questions
How is this different from the more specific ARIA naming rules like aria-command-name?
The role-specific rules only inspect elements that already carry a recognized ARIA role, such as button, textbox, or switch. This rule exists to catch elements that never got a role at all, or use markup so custom that no role-specific check applies, which is why it needs a human reviewer instead of a fixed DOM query.
Why is this classified as AI-assisted instead of fully automated?
Because judging whether an element is genuinely interactive, and whether every possible naming source has actually been exhausted, requires more contextual reasoning than a deterministic DOM query can reliably provide across arbitrary custom markup. RedFlag surfaces a candidate through its Review Labels feature and a human reviewer confirms it before it becomes a recorded violation.
Does an element need a visible role like button or link to be flagged by this rule?
No. This rule specifically targets elements that behave interactively, through a click handler or similar, without any role, tabindex, or naming attribute at all. A span with an onclick handler and nothing else is a common example, since it has neither a role a screen reader recognizes nor any way to reach it by keyboard, let alone a name.
Is a completely empty custom element always this rule and not one of the more specific ones?
Not necessarily. If the element has a recognized role like button or textbox, the more specific role-based rule applies instead, since a deterministic check can already cover it. This rule is reserved for elements the specific checks cannot classify, which is why it depends on a reviewer rather than a fixed rule.
Why is the impact rated critical instead of serious like the related ARIA rules?
Because this rule catches the broadest, most severe version of the failure: an interactive control with genuinely zero information reaching assistive technology, often also unreachable by keyboard. The role-specific rules at least confirm a role is announced even when the name is missing; this one can mean neither a role nor a name reaches the user at all.