Focus Management and Keyboard Interactions

Enabling focus using tabindex, and understanding tab order

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Table of Contents

This lesson preview is part of the The Approachable Guide to Accessible Components course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The Approachable Guide to Accessible Components, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The Approachable Guide to Accessible Components

In the last lesson, you learn that focus is activated when a user engages with an element by clicking, tapping, or pressing the tab key. You also explored how to style elements in the focus state using the focus pseudoclass. In this lesson, you will delve further into focus management and explore topics such as implicitly focused elements, enabling focus using tab index and understanding the tab order. Let's start off by talking about keyboard accessibility. If you remember the poor acronym that we talked about earlier in the course, the "O" in that acronym stands for "operable." And it represents a principle that emphasizes the usability of UI components and content navigation, ensuring that all interactive HTML elements such as links, buttons, and form inputs, for example, are not only functional with a mouse, but also fully operable via a keyboard. Although focus can be activated via mouse interaction, focus management is especially critical for users who rely predominantly on the keyboard to move around a web page. The next topic I want us to discuss is tab order, which, as the name implies, determines the secrets in which focus moves through a web page's interface. Ensuring a logical and intuitive tab order is crucial, where the visual arrangement of elements accurately reflects the actual tab order. By default, HTML elements that are intended for user interaction are implicitly focusable. These elements are automatically included in the tab order for seamless navigation. Conversely, elements like images, paragraphs, and headers are intentionally excluded from the tab order. This design choice ensures that focus is specifically directed towards elements that users can actively engage with, maintaining a practical and efficient user experience. In one way, I wanted to convey this concept is by going to the contact page on my podcast website. And I wanted to come here because there's a lot of interactive elements and it 's a simple page. And if I open up the dev tools in Firefox and go to the accessibility tab, there is a show tabbing order checkbox that you can check. And if I check that, it will show us the natural tab order for this website. And so if we see here, the first item in the tab order is the kind of the left panel here. And then next are all the interactive elements within the contact form. So we see we have first name, last name, and then it kind of goes in chronological order there based on interactive elements. And intentionally, the non-indirective elements like the contact us header and the paragraph underneath that are not in the natural tab order because you can't interact with them. So just wanted to give you guys a visual example of kind of how that looks like on a web page. But one thing to take caution on is if you're trying to alter the tab order with CSS. For example, when reordering flex items using the order property, as assistive technologies like screen readers cannot access the correct reading order. So let's revisit our kitten card example from a previous lesson and take a look at a rare use case where you actually do want to use the order property to reorder a flex item. So let's say, you know, our kitten card right now has the kitten for adoption at the top and then we have our image and then we have our description content. Let's say design comes back to us and it's like, hey, actually, I want the image to be displayed above the heading. So you could easily like actually move the image tag above the heading tag and achieve the desired result. But it kind of messes with the accessibility because ideally, you know, we have our card within an article element because we're trying to use semantic HTML after all. And you would have the heading tag next to kind of describe the content or the, you know, the main topic that the article is containing. So when we move the image, if we were to move the image element above, that would kind of mess up the order and make a little confusing for assistive technology. And one way to address this is instead of moving the image element up, instead, we will apply an order of negative one to the image CSS and that way the image will get shifted up, but we still maintain the order where the heading is first, then we have the image, then we have the description content. So that way, the screen reader or assistive technology will read out the card in the desired order. So this is, like I said, a rare use case where you do actually want to use CSS to reorder flex items, as real world example that I have with a design that I had to use and I just kind of wanted to showcase it that this is how you would maybe do it and how you would think through the process of when to apply it. The next topic I want us to discuss is tab index. For situations where you want to modify the tab order, you can leverage the tab index attribute. Tab index can be applied to any HTML element and accepts a range of numeric values. An element that includes the tab index attribute with a valid integer value can receive focus through JavaScript using the focus method or visual interaction by clicking with the mouse. A tab index with a negative value is most commonly used with tab index equals negative one, but the specific value is insignificant. When the tab index value is negative, it removes the element from the regular tab order rendering it inaccessible via the keyboard. However, the element can still receive focus by manually clicking on it. Tab index with a value of zero allows an HTML element to be included in the default keyboard navigation order. When element has tab index equals zero, it can receive focus through the tab key or programmatically invoking the focus method. Applying a zero tab index enables elements that are not inherently focusable to become accessible for keyboard users. Using a positive tab index value is not recommended and should be avoided. When an element has a tab index value greater than zero, it would be placed at the forefront of the tab order regardless of its position in the DOM. This can lead to confusion for screen readers and potentially disrupt the expected tab flow. If there is a need to adjust the tab order in this way, the recommended approach is to reposition the element higher in the DOM. Let's take a look at an example to really understand the concept of tab index. And if you scroll up to the top of the page, we'll see that MDN gives us a nice example that we can play around with. And if I click in the window here and press tab, the first item that gets focus is that input element at the top. If I press this tab the second time, the second item that receives focus is now that div after the input because it has that tab index of zero being applied to it. If I press tab a third time, the bottom input now receives focus. So let's tweak some of these tab index attributes values to kind of see what result we get. And the first thing I want to do is apply a tab index of negative one to the first input element. If you remember, input elements are interactive elements and therefore are implicitly focusable. So by applying a tab index of negative one, I am now removing that from the natural tab order. So when I apply that and then press tab the first time, now you see that it sk ips over that first input and actually goes to that first div instead. And if I was to press tab again, it would go back to the next input. The next, so let's go ahead and revert that and put it back in its natural state where there's no tab index. And the next thing I want to tweak is removing the tab index attribute from the div. Dives are not interactive elements and therefore by default, do are not implicitly focusable. So by removing that tab index equals zero, we're now putting it back into its default state, so to speak. And so now if I go in and tab through this window, the first item that receives focus will be the input element at the top. And we'll press tab a second time. We will now skip over those two divs because they're not focusable and it will go down to the bottom input. So the last technique we'll talk about is roving tab index, which is a focus technique that involves assigning tab index negative one to all children elements while setting tab index zero on the active item. The corresponding code for this technique includes a keyboard event listener that responds to arrow key presses. It dynamically adjusts the tab index values of the following items to tab index zero. Triggers are focus method and ensures that their previously focused element has its tab index negative one set. Upon reaching the last element in the list, the focus will wrap back around to the first item, creating a circular navigation flow. Similarly, when the first element is reached, it will return to the last item ensuring seamless navigation within the list. Using tab index is a technique that we will actually implement later on in this course in the interactive section. But for now, I want to show you an example by going to the APG website and looking at their toolbar example. If we tab into the toolbar component here that they have, if I press the right arrow key and say iterate through each item in this toolbar component, when I reach the end of this list and press the right arrow key again, it will loop me back to the first item, which is that B button. If I was to say reverse back and press the left arrow key and go backwards and when I reach the first item, it will take me back to the last item in this list. Roving tab index is just a nice way to have this circular navigation flow, a seamless flow that when you reach the last item in the list, it takes you back to either the front or the back of the list depending on where you are. [BLANK_AUDIO]