Skip to main content
Accessibility AccessLint 0.16

Non-interactive elements with tabindex='0' must have an interactive ARIA role so assistive technologies can convey their purpose.

About this AccessLint rule

When a non-interactive HTML element like a <div> or <span> receives tabindex="0", it becomes part of the keyboard tab order. Users can focus it with the Tab key, just like a button or link. But screen readers have no way to determine what the element actually does. They announce it generically, often as just "group" or with the text content alone, giving no indication that it's clickable, toggleable, or otherwise interactive.

This creates a confusing experience for screen reader users. A sighted user might see visual cues (a pointer cursor, a hover effect) that suggest interactivity, but a screen reader user hears no such cues. They land on the element, hear some text, and have no idea they're expected to activate it. Keyboard-only users face a related problem: they can focus the element, but without proper keyboard event handlers, pressing Enter or Space does nothing.

This rule checks that any non-interactive element with tabindex="0" also has an interactive ARIA role such as button, link, tab, menuitem, or similar. The role tells assistive technologies what kind of interactive control the element is, so they can announce it correctly.

Why this matters

This issue relates to WCAG Success Criterion 4.1.2: Name, Role, Value (Level A). This criterion requires that all user interface components have a name and role that can be programmatically determined. When a <div> with tabindex="0" acts as a button but has no role="button", assistive technologies cannot determine its role. The component fails this requirement.

Screen reader users are the most directly affected group. Without a declared role, they cannot distinguish between a focusable element that does something and one that is merely in the tab order by mistake. Keyboard-only users are also affected because elements lacking proper keyboard event handlers won't respond to expected key presses.

How to fix it

The best fix is to use a native interactive HTML element instead of a <div> or <span>. A <button> element already has the correct role, keyboard behavior, and focus handling built in. A <a href="..."> element already behaves as a link. Native elements are almost always the right choice.

If a native element truly cannot be used, three things are needed:

  1. Add an appropriate ARIA role to the element. Use role="button" if it triggers an action, role="link" if it navigates, role="tab" if it's part of a tabbed interface, and so on.
  2. Add keyboard event handlers. Buttons should respond to both Enter and Space. Links should respond to Enter.
  3. Make sure the element has an accessible name, either from its text content, an aria-label, or aria-labelledby.

Examples

Incorrect: focusable <div> with no role

This <div> is in the tab order but has no role. A screen reader might announce it as "Delete" with no indication that it's a button.

<div tabindex="0" onclick="deleteItem()">
Delete
</div>

Correct: use a native <button> element

The simplest fix is to replace the <div> with a <button>. No tabindex or role is needed because the element already has the correct semantics and keyboard behavior.

<button type="button" onclick="deleteItem()">
Delete
</button>

Correct: add a role and keyboard handling to the <div>

If a native element cannot be used, add role="button" and handle keyboard events. A button should activate on both Enter and Space.

<div
tabindex="0"
role="button"
onclick="deleteItem()"
onkeydown="if(event.key === 'Enter' || event.key === ' ') { event.preventDefault(); deleteItem(); }">
Delete
</div>

Incorrect: focusable <span> used as a link

This <span> navigates to another page but has no role or keyboard support.

<span tabindex="0" onclick="location.href='/settings'">
Settings
</span>

Correct: use a native <a> element

<a href="/settings">
Settings
</a>

Correct: add role="link" and keyboard handling

<span
tabindex="0"
role="link"
onclick="location.href='/settings'"
onkeydown="if(event.key === 'Enter') { location.href='/settings'; }">
Settings
</span>

In every case, using native HTML elements (<button>, <a>, <input>, <select>) is preferred over adding ARIA roles to non-interactive elements. Native elements handle focus, keyboard interaction, and role announcements automatically, reducing the chance of errors.

Detect accessibility issues automatically

Rocket Validator scans your site with complementary accessibility engines, helping teams find issues across every page.

Help us improve our guides

Was this guide helpful?
๐ŸŒ Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
$7 / 7 days

Pro Trial

Full Pro access. Cancel anytime.

Start Pro Trial โ†’

Join teams across 40+ countries