# Elements should not have tabindex greater than 0, which disrupts natural tab order.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/accesslint/0.16/keyboard-accessible/tabindex
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Setting a `tabindex` attribute with a value greater than 0 on an HTML element forces that element to the front of the keyboard tab order, regardless of where it appears in the document. This breaks the natural reading and navigation sequence that keyboard users depend on.

When a user presses the Tab key, the browser moves focus through interactive elements in DOM source order. A positive `tabindex` (such as `tabindex="1"`, `tabindex="5"`, or `tabindex="100"`) overrides this behavior by pulling the element ahead of all elements with `tabindex="0"` or no `tabindex` at all. If multiple elements have positive values, they are ordered by their values first, then by DOM position. The result is a tab sequence that no longer matches the visual layout of the page.

This is a problem for several groups of users:

- Keyboard-only users, who rely on a predictable tab order to navigate forms, links, and controls. A scrambled sequence makes it difficult to find and interact with elements efficiently.
- Screen reader users, who expect focus order to match the reading order of the page. When focus jumps unexpectedly, the context of the surrounding content is lost.
- Users with cognitive disabilities, who benefit from consistent, predictable navigation patterns.

This rule relates to WCAG 2.2 Success Criterion 2.4.3: Focus Order (Level A), which requires that when a page can be navigated sequentially, components receive focus in an order that preserves meaning and operability. Positive `tabindex` values directly conflict with this requirement because they create a tab order that diverges from the DOM and visual order.

## How to fix it

Remove any `tabindex` value greater than 0. In nearly all cases, the correct approach is one of:

- **Use `tabindex="0"`** to place a non-interactive element (like a `<div>` or `<span>`) into the natural tab order at its DOM position. This is useful when building custom interactive widgets.
- **Use `tabindex="-1"`** to make an element focusable via JavaScript (`element.focus()`) without placing it in the tab order. This is common for elements that receive focus programmatically, such as modal containers or error messages.
- **Use no `tabindex` at all** on natively interactive elements like `<a>`, `<button>`, and `<input>`. These elements are already in the tab order by default.

If the goal is to change the order in which elements receive focus, rearrange the elements in the DOM instead. The DOM order should match the intended visual and logical reading order.

## Examples

### Incorrect: positive tabindex values

```html
<form>
  <label for="email">Email</label>
  <input type="email" id="email" tabindex="2">

  <label for="name">Name</label>
  <input type="text" id="name" tabindex="1">

  <button type="submit" tabindex="3">Submit</button>
</form>
```

In this example, the user tabs to the name field first (`tabindex="1"`), then the email field (`tabindex="2"`), then the submit button (`tabindex="3"`), even though the email field appears first visually. This is confusing and breaks the expected top-to-bottom flow.

### Correct: natural tab order through DOM position

```html
<form>
  <label for="name">Name</label>
  <input type="text" id="name">

  <label for="email">Email</label>
  <input type="email" id="email">

  <button type="submit">Submit</button>
</form>
```

With no `tabindex` attributes, the browser follows the DOM order. The tab sequence matches what the user sees on screen: name, email, submit.

### Correct: using tabindex="0" for a custom widget

```html
<div role="button" tabindex="0">
  Save changes
</div>
```

A `<div>` is not natively focusable. Setting `tabindex="0"` adds it to the tab order at its natural DOM position. (This element would also need keyboard event handlers for Enter and Space to be fully accessible.)

### Correct: using tabindex="-1" for programmatic focus

```html
<div id="error-summary" tabindex="-1" role="alert">
  Please correct the errors below.
</div>
```

This element is not in the tab order, but JavaScript can call `document.getElementById("error-summary").focus()` to move focus to it when validation errors appear.
