# tabindex Attribute

> Canonical HTML version: https://rocketvalidator.com/glossary/tabindex-attribute
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `tabindex` attribute is an HTML attribute that controls whether an element is focusable via keyboard navigation, and optionally determines its position in the sequential tab order of the page.

The `tabindex` attribute is a global HTML attribute that can be applied to any element to influence how it participates in keyboard navigation. By default, only interactive elements like `<a>`, `<button>`, `<input>`, `<select>`, and `<textarea>` are included in the tab order. The `tabindex` attribute gives developers the ability to make non-interactive elements focusable, remove elements from the tab order, or programmatically manage focus — all of which are critical for building accessible web experiences.

The attribute accepts an integer value, and its behavior varies significantly depending on whether that value is negative, zero, or positive. Understanding these three modes is essential for anyone working with keyboard accessibility, as misuse of `tabindex` is one of the most common sources of confusing and inaccessible tab order on the web.

## Why the tabindex attribute matters

Keyboard navigation is foundational to web accessibility. Users who rely on keyboards, switch devices, or screen readers depend on a logical and predictable tab order to move through a page. The `tabindex` attribute directly controls this experience, making it a powerful but potentially dangerous tool.

When used correctly, `tabindex` enables developers to create custom interactive widgets — such as dropdown menus, modals, and tab panels — that are fully operable via keyboard. Without it, custom components built from `<div>` or `<span>` elements would be completely unreachable by keyboard users, violating WCAG 2.1 Success Criterion 2.1.1 (Keyboard) and Success Criterion 2.4.3 (Focus Order).

When used incorrectly — particularly with positive values — `tabindex` can create a disjointed, unpredictable tab order that confuses all keyboard users, including those using assistive technologies. A page where focus jumps erratically between unrelated sections is disorienting and can make content effectively unusable for people with motor or cognitive disabilities.

## How the tabindex attribute works

### `tabindex="0"` — Add to natural tab order

Setting `tabindex="0"` on an element makes it focusable and places it in the natural document tab order (determined by its position in the DOM). This is the most common and recommended use of `tabindex` for making custom interactive elements keyboard-accessible.

### `tabindex="-1"` — Programmatically focusable only

A value of `-1` (or any negative integer) makes an element focusable via JavaScript using the `focus()` method, but removes it from the sequential tab order. Users cannot reach the element by pressing Tab. This is useful for managing focus in components like modals and focus traps, where you need to move focus to an element without placing it in the regular tab flow.

### Positive `tabindex` values — Avoid these

A positive value (e.g., `tabindex="1"`, `tabindex="5"`) places the element ahead of all elements with `tabindex="0"` or no `tabindex` in the tab order. Elements with positive values are visited first, in ascending numeric order, before the natural DOM order takes over. While this might seem useful, it almost always leads to a confusing and fragile tab order. The WCAG and WAI-ARIA authoring practices strongly discourage using positive `tabindex` values.

### Interaction with semantic HTML

Interactive HTML elements like `<button>` and `<a href="...">` are natively focusable and already included in the tab order — there is no need to add `tabindex="0"` to them. Relying on semantic HTML whenever possible reduces the need for `tabindex` altogether and ensures built-in keyboard behavior, focus indicators, and screen reader announcements work without extra effort.

## Code examples

### Bad example — Positive tabindex creating unpredictable order

In this example, positive `tabindex` values force the "Submit" button to be focused before the input fields, which is confusing for users:

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

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

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

A keyboard user pressing Tab would focus "Submit" first, then "Name", then "Email" — the opposite of the visual and logical order.

### Good example — Using natural DOM order with `tabindex="0"`

Let the DOM order determine the tab sequence. If you need a custom element to be focusable, use `tabindex="0"`:

```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>
```

No `tabindex` is needed here because all elements are natively interactive. The tab order follows the DOM naturally.

### Bad example — Non-focusable custom button

A `<div>` styled to look like a button is unreachable by keyboard:

```html
<div class="btn" onclick="submitForm()">
  Submit
</div>
```

### Good example — Making a custom widget focusable

If you must use a non-interactive element as a control, add `tabindex="0"` along with the appropriate ARIA role and keyboard event handlers:

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

Even better, use a semantic `<button>` element instead to get focus, keyboard interaction, and screen reader support for free:

```html
<button type="button" class="btn" onclick="submitForm()">
  Submit
</button>
```

### Good example — Using `tabindex="-1"` for focus management

When opening a modal dialog, move focus to the dialog container without adding it to the tab order:

```html
<div id="modal" role="dialog" aria-labelledby="modal-title" aria-modal="true" tabindex="-1">
  <h2 id="modal-title">Confirm Action</h2>
  <p>Are you sure you want to proceed?</p>
  <button type="button">Yes</button>
  <button type="button">No</button>
</div>

<script>
  document.getElementById("modal").focus();
</script>
```

The `tabindex="-1"` allows JavaScript to move focus to the modal container when it opens, while the user's subsequent Tab presses move naturally to the interactive elements inside.
