The HTML tabindex attribute is used to manage keyboard focus. Used wisely, it can effectively handle focus within web widgets. Used unwisely however, the tabindex
attribute can destroy the usability of web content for keyboard users.
The tabindex
attribute indicates that an element can be focused on, and determines how that focus is handled. It takes an integer (whole number) as a value, and the resulting keyboard interaction varies depending on whether the integer is positive, negative or 0.
To understand why the tabindex
attribute has such a powerful effect on usability, it’s necessary to know something of the way keyboard interaction works. A keyboard user will typically move through web content using the tab key, moving from one focusable element to the next in sequential order.
Certain interactive HTML elements like links and form controls are focusable by default. When they’re included in a web page, their sequential order is determined by the source order of the HTML.
<label for="username">Username:</label>
<input type="text" id="username">
<label for="password">Password:</label>
<input type="password" id="password">
<input type="submit" value="Log in">
A keyboard user would tab first to the username field, then the password field, and finally to the log in button. All three elements take focus by default, and they’re accessed in the order that they appear in the source code. In other words, there’s no need to explicitly set the tabindex
because it’s all handled effortlessly in the browser.
tabindex=0
When tabindex
is set to 0
, the element is inserted into the tab order based on its location in the source code. If the element is focusable by default there’s no need to use tabindex
at all, but if you’re repurposing an element like a <span>
or <div>
, then tabindex=0
is the natural way to include it in the tab order.
It’s worth mentioning at this point that it’s easier to use a focusable HTML element wherever possible. For example, when you choose to use a <button>
or <input type="checkbox">
, keyboard focus and keyboard interaction are handled automatically by the browser. When you repurpose other elements to create custom widgets, you’ll need to provide keyboard focus and interaction support manually.
tabindex=-1
When tabindex
is set to a negative integer like -1
, it becomes programmatically focusable but it isn’t included in the tab order. In other words, it can’t be reached by someone using the tab key to navigate through content, but it can be focused on with scripting.
An example is moving focus to a summary of errors returned by a form. The summary would typically be located at the start of the form, so you want to draw the attention of screen reader/magnifier users to it, and to position all keyboard-only users at the start of the form so they can begin correcting any errors. You don’t want the error summary itself to be included in the tab order of the page though.
<div role="group" id="errorSummary" aria-labelledby="errorSummaryHeading" tabindex="-1">
<h2 id="errorSummaryHeading">Your information contains three errors</h2>
<ul>
...
</ul>
</div>
tabindex=1+
It’s when tabindex
is set to a positive integer that things get problematic. It imposes a tab order on the content that bears no resemblance to the expected tab order.
<label for="username">Username:</label>
<input type="text" id="username" tabindex="3">
<label for="password">Password:</label>
<input type="password" id="password" tabindex="1">
<input type="submit" value="Log in" tabindex="2">
In this example the visual presentation of the form would be as expected: Username and password fields, followed by the log in button. The tab order would make no sense at all however. Focus would move first to the password field, then the log in button, and finally to the username field.
Things get worse when you realise that the password field would be the first focusable element on the page containing the form. It doesn’t matter how many focusable elements appear in the source order/visual presentation before the password field, the tabindex
of 1
means it’ll be the first element to receive focus on the page.
The tabindex
attribute is versatile, and it has the capacity to improve or destroy usability for keyboard-only users. When you think about using the tabindex
attribute, keep these things in mind:
- Use
tabindex=0
to include an element in the natural tab order of the content, but remember that an element that is focusable by default may be an easier option than a custom control - Use
tabindex=-1
to give an element programmatic focus, but exclude it from the tab order of the content - Avoid using
tabindex=1+
.
Further reading
- HTML definition of Interactive content, is content that is specifically intended for user interaction.
- HTML tabindex definition.
- ARIA – providing keyboard focus.