Understanding tabindex – keyboard accessibility
Tags: a11y, webdev, webaccessibility
Published: 2020-06-07 09:22:06

As a web developer, you are required to ensure that your users have the best of experience while using your product. Traversing your website with a keyboard is one of the fastest ways. Not only this, filling a form which is keyboard accessible takes 1/2 the time, if compared to filling the form using a mouse-keyboard duo.

But the thing is, accessibility is for the people who are either using screen readers or are using assistive technologies. My main aim here is to put down notes on `tabindex` and how it plays a major role in making your forms and DOM (Document Object Model) keyboard accessible.

# How to find active element?
One of the problems while making a form keyboard accessible with `tabindex` was to find out where the fuck I actually was in the DOM while pressing the TAB key. At times it drove me nuts but then I had to find a better a solution. Turns out, its pretty simple.  

```javascript
document.activeElement
```
Fire up the chrome/firefox developer tools in your browser and once you are done TAB-bing through the form and want to know which element is in focus, use “document.activeElement” and press Enter.  

### Firefox developer tools
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nftpofoxrtoyeuv7nz69.png)  

The most amazing thing about this is that when you hover on active element thrown by the developer tools, you’ll see something like in the picture above, and below!  

### Chrome developer tools
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7p9ru6e85jabd7oqf17o.png)

***  

# Understanding `tabindex` and how it works  
`tabindex` is used for 2 major reasons:  

1. to check if the element is focusable
2. at what point/in what order the element comes into focus  

## Focus order  
There are 6 HTML elements which has the ability to focus by default i.e. you don’t have to explicitly put tabindex attribute.  

1. `<a>` with `href` attribute
2. `<link>` with `href` attribute
3. `<button>`
4. `<input>` without the `type="hidden"`
5. `<textarea>`
6. `<select>`  

This means, these 6 elements will have the focus during the TAB-ing behavior and the screen readers will be able to read these elements without any extra help!  

***  

# Important note for Frontend Developers  
The order will highly depend on the order in which these elements are coded in .html files.

For example, if you want to use `<a>` and `<input>` under the same parent, and you want the `<input>` to have focus before the `<a>`, then make sure you `<input>` has been coded before `<a>` in the .html file.

### position:absolute  
Therefore, if you are positioning elements with `position: absolute` then make sure the absolutely positioned element is AFTER the element you want focused on! I learnt this the hard way so want to give you a heads up!  

```html
<!-- First in order -->
<button type="button">I will be first in focus</button>

<!-- Second in order -->
<a href="javascript:void(0)">I will be focused second</a>
```

> Testing playground: You’ll learn it better when you see it in practice! So stop being a lazy-ass and try these examples on [CodePen](https://codepen.io/pen/) here.  

***  

# tabindex values: -1, 0, +1  
The tabindex values can be negative, 0 or positive.  

**1. Negative:** When the element has negative focus, neither it will be read by screen readers nor it will come in the TAB-ing sequence. A negative tabindex (say -1) will remove the element from the ordering sequence completely. A negative value is a negative value. This means, there is no difference between -1 and -145 or -9999.

If you want to purposefully ignore an element in the TAB-ing sequence, just give it a negative tabindex.  

```html
<button type="button">Sample Button 1</button>

<!-- This will be ignored -->
<button type="button" tabindex="-1">I will be ignored</button>

<button type="button">Sample Button 2</button>
```
> Testing playground: You’ll learn it better when you see it in practice! So stop being a lazy-ass and try these examples on [CodePen](https://codepen.io/pen/) here.  

<br/>
**2. Zero:** This is the default value. The 6 elements we talked about, will have `tabindex="0"` by default when the DOM gets built in the browser. But if you want to focus on a non-focusable element like `<div>` or `<span>`, you can explicitly give it a `tabindex` attribute with value 0. Once you do that, the element will follow the default TAB-ing order.  

```html
<button type="button">Sample Button 1</button>

<!-- Making non-focusable element focusable -->
<div tabindex="0">Please focus on me</div>

<button type="button">Sample Button 2</button>
```
> Testing playground: You’ll learn it better when you see it in practice! So stop being a lazy-ass and try these examples on [CodePen](https://codepen.io/pen/) here.  

<br/>
**3. Positive:** The positive `tabindex` will place the element having a positive `tabindex` in the order sequence and the order will be decided based on the value. The TAB-ing will happen in the ascending order.  

```html
<button type="button" tabindex="2">Sample Button 1</button>
<!-- This will be ignored, even though it has a tab-index -->
<button type="button" tabindex="1">Sample Button 2</button>
<button type="button" tabindex="3">Sample Button 3</button>
```
> Testing playground: You’ll learn it better when you see it in practice! So stop being a lazy-ass and try these examples on [CodePen](https://codepen.io/pen/) here.  

<br/>
The first-focus will be on **Sample Button 1** having `tabindex` value of 2. The next TAB will take you to **Sample Button 3**, completely ignoring **Sample Button 2**. The TAB-ing will NEVER happen in decreasing order, therefore you will never reach **Sample Button 2**.  

### The catch
Positive `tabindex` values are discouraged and are an antipattern. According to [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex), never use positive `tabindex` values and stick to the default value of 0. But if there is a use-case wherein you want to have a positive `tabindex` value to change the order of focus sequence, then take a stop the fuck right there. Take a step back and a deep breath while you are at it! Now try to change the order of elements in your HTML file/source code!

**TAB-ing must be fixed with correct order of HTML elements within the source code.**  

***  

# In Conclusion…
I have been working as a web developer for more than 1.5 years now and I am a self-learner developer, like the majority out there. The thing with self learning is that you learn stuff when the opportunity knocks on the door to learn that shit. And this was no different. I learned about web accessibility recently and the sheer importance of it.

As web developers we need to understand that we enjoy the privilege to develop products and projects that will be used by [speech and visually impaired](https://www.w3.org/WAI/people-use-web/abilities-barriers/) people as well, apart from the rest of the world. Therefore the next time you are writing code in an HTML file, ensure that it adheres to web accessibility standards.

Checkout more cool stuff [here](https://a11yproject.com/).  

***

Originally published at [adityatyagi.com](https://adityatyagi.com)