How and when to use the tabindex attribute

tabindex is a global attribute that can be applied to most HTML elements with content. It controls two things:

  1. If an element is focusable, either by an input method such as the keyboard, or programatically such as with the focus() method; and
  2. At what point an element becomes focusable when a user is interacting with the page via a keyboard

Focus order

To understand how the tabindex attribute works, we first need to understand how focus is controlled on a page.

There are six 1 HTML elements which, by default, are focusable:

  • <a> elements with an href attribute
  • <link> elements with an href attribute
  • <button> elements
  • <input> elements that are not type="hidden"
  • <select> elements
  • <textarea> elements

By default, only these elements can be brought into focus either with a user tabbing around the page with a keyboard or via the focus() method in Javascript.

document.querySelector("a").focus();

Without any intervention, calling focus() on any other element simply will not work.

document.querySelector("div").focus();
Will not work

The order in which these elements are placed in the source HTML document controls the order in which they become focusable when navigating with a keyboard.

Although this default behaviour covers most of the interaction we would need, there may be cases where we want to remove, add, or re-arrange items in the focus order. This is where the tabindex attribute becomes handy.

How to use tabindex

The tabindex attribute can be applied to almost any element, whether it is by default focusable or not. The value of the attribute must be a valid integer and can either be negative, positive, or exactly zero.

Negative tabindex values

A negative tabindex, for example -1, will omit the element from the focus order entirely. A user navigating the page using a keyboard will not be able to access the element at all.

<button type="button">Click me to start, then press the "tab" key</button>
<button type="button">I’ll be in focus first</button>
<button type="button" tabindex="-1">I won’t be in focus :(</button>
<button type="button">I’ll be in focus last</button>




 

The exact negative value chosen doesn’t actually matter. Since any negative value will remove the element from focus, there is no difference if the value is -1 or -99999. Therefore, for readability and consistency, it is best to stick with -1.

A tabindex value of zero

A tabindex equals to exactly zero will place the element in the default focus order, determined by its position in the source HTML. It can be applied to elements that are not typically focusable, and will add them to the natural focus order as if they were.

<button type="button">Click me to start, then press the "tab" key</button>
<button type="button">I’ll be in focus first</button>
<div tabindex="0">I’m a DIV and will be in focus second</div>
<button type="button">I’ll be in focus last</button>


I’m a DIV and will be in focus second

 

Positive tabindex values

Finally, a positive tabindex will place the element in the focus order, but it’s position will be determined by the specific number, starting from 1 and going up. Elements with a positive tabindex will also be placed in front of elements that don’t have a tabindex attribute.

<button type="button" tabindex="1">I’m the first focusable item on the page</button>
<button type="button" tabindex="500">I’m the second</button>

To test this out, click on the URL bar of your browser, then hit tab. You'll see that the first two focusable items on this page are the buttons below, even though they are in the middle of the source HTML.


 

Programmatic focus and tabindex

Besides controlling which elements can be focusable via the keyboard and focus order, the tabindex attribute also controls which elements can be focusable via Javascript.

Adding the tabindex attribute to an element, regardless of the value, makes it focusable via Javascript. This means that we can make elements that are previously unfocusable to be focusable via Javascript, without also making them able to be focused via the user tabbing around using their keyboard.

Let’s take this <div>, for example, with a negative tabindex.

<div tabindex="-1">I'm a div</div>

If we were to navigate using the keyboard, we will see that it is not able to grab focus.

I'm a div

 

However, we can bring focus to it using the focus() method.

<button type="button" 
        onclick="document.getElementById('demo-div').focus();">
        Click me to focus the DIV
</button>
<div id="demo-div" tabindex="-1">I'm a div</div>

I'm a div

 

Next, we’ll see how this difference between tab and programmatic focus makes the tabindex attribute useful.

When to use tabindex

The tabindex attribute can be very useful, but has potentially destructive consequences if not used correctly. Each category of tabindex value should be used in different circumstances.

When to use a negative tabindex value

As we have covered, a negative tabindex value will remove the element from tab focus, but can add elements to programmatic focus.

A great example of when this is useful is modals. Modal containers are typically unfocusable elements like <div> or <section>. When a modal window is open, we may want to move focus to it so that screen readers will read out its content. But, we don’t want the modal container itself to be able to receive tab focus. This can be achieved using a negative tabindex.

<div id="modal" tabindex="-1">
    <!-- Modal content -->
</div>

<script>
function openModal() {
    document.getElementById("modal").focus();
    
    // Other stuff to show modal
}
</script>

When to use a tabindex value of zero

A tabindex of zero is typically used either to add focus back to elements that it was programatically removed from.

Another good use case for this value is for custom elements. For example, we may need to create a custom button element, which will not be focusable by default because it's not actually a <button>. We can add this functionality back with the tabindex attribute, and specify its focus order as any regular button element would have.

<my-custom-button tabindex="0">Click me!</my-custom-button>

When to use a positive tabindex value

There is almost no reason to ever use a positive value to tabindex, and it is actually considered an anti-pattern. If you’re finding the need to use this value to change the order in which elements become focusable, it is likely that what you actually need to do is change the source order of the HTML elements.

#1 - I excluded the menuitem element as it’s no longer valid HTML
blog comments powered by Disqus