Skip to main content
Accessibility Axe Core 4.11

Elements in the focus order should have an appropriate role

About This Accessibility Rule

When users navigate a web page using a keyboard or screen reader, they move through what’s called the “focus order” — the sequence of interactive elements that receive focus. Each time an element receives focus, a screen reader announces its role (e.g., “button,” “link,” “checkbox”) along with its name and state. This role is how users understand what type of control they’ve landed on and what actions they can take.

If a focusable element has no role — for example, a <div> made focusable with tabindex="0" — the screen reader may read the element’s text content but will provide no context about what the element is. The user hears text but has no idea whether to press Enter, type input, or toggle a state. Similarly, if an element has an inappropriate role like presentation or an abstract role like widget, assistive technologies cannot convey meaningful interaction patterns.

This issue primarily affects blind and deafblind users who rely on screen readers, and users with motor disabilities who navigate exclusively with a keyboard. Without proper role information, these users cannot efficiently or accurately interact with page controls.

Why Roles Matter

This rule aligns with accessibility best practices recommended by Deque and RGAA. While it doesn’t map to a single WCAG success criterion, it supports several principles:

  • WCAG 4.1.2 (Name, Role, Value): All user interface components must expose their role, name, and state to assistive technologies.
  • WCAG 2.1.1 (Keyboard): All functionality must be operable through a keyboard. Meaningful role information is essential for keyboard users to understand what they can do with a focused element.

When an element in the focus order has a valid, appropriate role, screen readers can:

  1. Announce the type of control (e.g., “button,” “textbox,” “menu item”).
  2. Inform users of available interactions (e.g., “press Enter to activate,” “use arrow keys to navigate”).
  3. Communicate state changes (e.g., “checked,” “expanded”).

How to Fix the Problem

Use Native HTML Elements First

The simplest and most reliable fix is to use the correct native HTML element. Native elements like <button>, <a>, <input>, and <select> come with built-in roles, keyboard behavior, and accessibility support — no extra attributes needed.

Add ARIA Roles to Custom Widgets

If you must use a non-semantic element (like <div> or <span>) as an interactive control, you need to:

  1. Add an appropriate role attribute (e.g., role="button", role="checkbox", role="tab").
  2. Ensure all required keyboard interactions are implemented.
  3. Manage ARIA states and properties (e.g., aria-checked, aria-expanded).

Avoid Abstract Roles

ARIA defines abstract roles like command, input, landmark, range, section, sectionhead, select, structure, and widget. These exist only as part of the role taxonomy and must never be used directly on elements. Always use a concrete role instead.

Remove tabindex from Non-Interactive Elements When Possible

If an element doesn’t need to be interactive, consider removing its tabindex attribute entirely so it doesn’t appear in the focus order.

Appropriate Roles for Interactive Content

Here are some common categories of valid roles for focusable elements:

  • Widget roles: button, checkbox, combobox, link, listbox, menu, menuitem, menuitemcheckbox, menuitemradio, option, radio, scrollbar, slider, spinbutton, switch, tab, textbox, treeitem
  • Composite widget roles: grid, menubar, radiogroup, tablist, toolbar, tree, treegrid
  • Landmark roles: banner, complementary, contentinfo, main, navigation, region, search
  • Document structure roles: dialog, alertdialog, application, document, log, status, timer, tooltip

Examples

Incorrect: Focusable Element With No Role

This <div> can receive focus, but a screen reader won’t announce what it is:

<div tabindex="0" onclick="submitForm()">
  Submit
</div>

A screen reader user will hear “Submit” but won’t know it’s meant to be a button.

Correct: Using a Native HTML Button

<button type="button" onclick="submitForm()">
  Submit
</button>

The <button> element has a built-in button role. The screen reader announces “Submit, button.”

Correct: Adding an ARIA Role to a Custom Widget

If you cannot use a native <button>, add the appropriate role and keyboard support:

<div role="button" tabindex="0" onclick="submitForm()" onkeydown="handleKeydown(event)">
  Submit
</div>

Now the screen reader announces “Submit, button.” You must also implement onkeydown to handle Enter and Space key presses, since a <div> doesn’t natively support those interactions.

Incorrect: Using an Abstract Role

<div role="command" tabindex="0">
  Save
</div>

The command role is abstract and must not be used on elements. Assistive technologies will not recognize it as a valid role.

Correct: Replacing the Abstract Role

<div role="button" tabindex="0" onkeydown="handleKeydown(event)">
  Save
</div>

Incorrect: Non-Interactive Role on a Focusable Element

<span role="paragraph" tabindex="0" onclick="openMenu()">
  Options
</span>

The paragraph role is not interactive. The element will not behave as expected for assistive technology users, and may not even receive focus in some screen readers.

Correct: Using an Appropriate Widget Role

<span role="button" tabindex="0" onclick="openMenu()" onkeydown="handleKeydown(event)">
  Options
</span>

Incorrect: Focusable Custom Checkbox Without a Role

<div tabindex="0" class="custom-checkbox" onclick="toggleCheck(this)">
  Accept terms
</div>

Correct: Custom Checkbox With Proper Role and State

<div role="checkbox" tabindex="0" aria-checked="false" onclick="toggleCheck(this)" onkeydown="handleKeydown(event)">
  Accept terms
</div>

The role="checkbox" tells the screen reader this is a checkbox, and aria-checked communicates its current state. Remember to update aria-checked in your JavaScript when the state changes.

Help us improve our guides

Was this guide helpful?

Detect accessibility issues automatically

Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.

Ready to validate your sites?
Start your free trial today.