Google Sheets iconSwift icon
Published at
Updated at
Reading time

This post is part of my Today I learned series in which I share all my learnings regarding web development.

Focus handling is essential for accessible and well functioning interfaces. Especially when building complex interfaces with custom UI components we all should check if we can achieve our goals by using the keyboard only.

The tabindex html element attribute plays a big role when dealing with focus. So let's quickly recap what values you can set:

  tabindex="0" -> element should be focusable 
  in sequential keyboard navigation
<foo tabindex="0">Foo</foo>

  tabindex="-1" -> element should be focusable, 
  but should not be reachable 
  via sequential keyboard navigation
<bar tabindex="-1">Bar</bar>

You can also set positive numbers but this is considered to be an anti-pattern because you can define the focus order of elements and this usually harms more than it helps.

With the tabindex attribute you can control if elements can be focusable and if they should be reachable with keyboard navigation. This can become very useful when you want to lead the focus to elements after certain user interactions.

I use tabindex when it makes sense but I never heard the term "roving tabindex" until recently (or I simply forgot).

This "roving tabindex" is a technique to maintain focus state. Think of a group of a few custom radio elements. What should be the behavior when you "tab" into this group? I'm expecting the following:

- tab into         👉🏻 the active radio gets focus
- left/right arrow 👉🏻 another radio element get focus
- another tab      👉🏻 focus goes out of the radio group
- tab back in      👉🏻 the last active radio get focus

This can be achieved with a smart usage of setting tabindex=0 and tabindex=-1. The active element then has tabindex="0" to be get focus when the user "tabs" in and all the other elements tabindex="-1" to not be reachable by the keyboard. A little bit of JavaScript then toggles the given states in case another elements becomes active.

&lt;radio tabindex="-1"&gt;1&lt;/radio&gt;
&lt;radio tabindex="-1"&gt;2&lt;/radio&gt;
&lt;radio tabindex="0"&gt;3&lt;/radio&gt;
&lt;radio tabindex="-1"&gt;4&lt;/radio&gt;
&lt;radio tabindex="-1"&gt;5&lt;/radio&gt;

And this technique of toggling tabindex is called "roving tabindex". I discovered that Rob Dodson even recorded a whole a11ycast episode on this topic so make sure to check this one out.

And that's it for today. ;)

Related Topics

Related Articles