Website Accessibility, v3

Tab Trapping Exercise

Jon Kuperman
Bloomberg
Website Accessibility, v3

Lesson Description

The "Tab Trapping Exercise" Lesson is part of the full, Website Accessibility, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Students are instructed to code a tap-trapping feature for the modal window. Tabbing from the cancel button should cycle back to the first input field. Shift-tabbing from the first input field should cycle back to the cancel button.

Preview
Close

Transcript from the "Tab Trapping Exercise" Lesson

[00:00:00]
>> Jon Kuperman: So, with that, we will go into our 3rd exercise, which is tab trapping. So if we go back over to the website, and we go back to this area here, and we go to exercise 3 tab trapping, we'll notice that we have quite a simple page. And on this page we have a modal form.

[00:00:16]
And so you click open the modal and it opens this contact thing, and it sort of works how you would expect where you open it and it's got a form to it, and then you hit cancel and it closes it. But the thing that you'll notice, like I had described before, is if you go ahead and you open it and you begin tabbing through the elements here, that once you get to the cancel button, which is the last tab able element, if you hit tab again, it actually takes you up and starts tabbing you through, like my Chrome tabs up here.

[00:00:42]
I've completely lost the plot here, and now I'm tabbing back through the website and then finally I get back into the modal. And so kind of your task here, and the source code, again is all in this HTML with a little bit of JavaScript here, is to create a tab trap.

[00:00:56]
And so the idea being that in some way there's multiple ways to solve this. When you are on the last element and you hit tab, it should instead of letting you go, it should send you back to the first element. And similarly, when you're on the first element and you hit shift tab, it should send you to the last element.

[00:01:17]
All right, cool. So, yeah, welcome back. Let's kinda go through this tab trapping one together. Hopefully people found it okay. There's, I think, a couple of different ways we can solve it. And again, yeah, the bigger takeaway, I guess, is like starting to understand more and more what the usability concerns are for people that are doing keyboard only or using screen readers.

[00:01:38]
So just as a reminder, we'll go back into the example here. We've got this modal and the modal already does a bunch of cool things for us. It's like if we hit escape or click away, it should close and we can tab through the form elements, which is great.

[00:01:51]
But the kinda problem that we were looking to solve was that when you tab to the end and then hit tab again, your focus gets moved back up here. Similarly, if you were to shift tab to the beginning and then shift tab, it gets moved back behind here.

[00:02:03]
And this is not what we are looking for. So kinda jumping into the code a little bit. Feel free to follow along if you didn't do the exercise, but otherwise, however you did it, I'm sure is fine. But we've got these kind of two event listeners. We've got the handle escape key and the handle tab key.

[00:02:18]
And so we kinda want to just implement this handle tab key event. So we can just do a handle tab key, and we can grab the event, and then I think there's a couple of ways that we could go about doing this. I guess if we can just log kinda some things out here and open the DevTools.

[00:02:39]
So when we hit tab, we get access to this E, and the E, if we log it out has a bunch of good stuff on it. Yeah, it's got like a code and a key that are both tabs. So I think we can do something like, okay, so we're in here.

[00:02:54]
If the E key is not and then whatever that was tab, then we can just return. Right, so we only wanna care about the tab key, and then what we'll do is something like if. Yeah, there's like a shift key property, so we'll do if E shift key.

[00:03:11]
And here we know going backwards or however we wanna call it, and then else. And then here we know going forwards and then, for those that dug through the code, I provided a helper method. This does something very similar to the focusable library that I had highlighted earlier.

[00:03:33]
So essentially just returning a big string of all of the tap able elements that you can find. So this one is constrained to just the ones that we have in our little app. But you could basically do the same thing. So basically it's like this array of all of the different tap able elements.

[00:03:49]
So I think the things that we'll sort of wanna do are, if we're going backwards and we are on the first one, if we're shift tabbing and we're on the first element, then we would wanna do something like prevent default and set focus to last element, something like that.

[00:04:13]
And then similarly, if we're going forwards and we're on the last element, then we would wanna prevent default and set focus to first element, basically, something like that. I think there's lots of different ways you could solve it. So in here, if we're not on the tab, then we return.

[00:04:29]
We can make a focusable elements equals what was our get focusable elements. So this should be a nice list of things we can make. They're like first element equals focusable elements, the first one, and then const last element equals the focusable elements at focusable elements length minus one.

[00:04:49]
So that should give us the first, the last, and then we could even make like a const current element if we wanted, using again from the previous slides. There's a couple ways we can do this, but we can use that document active element. And so if we go ahead and console log out first, last current, something like that.

[00:05:08]
And then go ahead and play this through and refresh. Okay, cool. So the first element is the input name that looks right, the last element is the button close modal that also looks right, and then the current element would be the input name. That seems good to me.

[00:05:24]
So then here I think we can do something like, okay, if the current element is equal to the first element, then we're in our little things, we can do our E prevent default and then again using the APIs that we learned about the Focus API, so then we can call last element focus, right?

[00:05:42]
So if it's a tab and it's a shift and we're on the 1st, don't do anything normal, instead send you to the last. And then we'll do the same thing here. So we'll do if the current element is equal to the last element. So if it's a tab and it's not a shift and we're on the last element, then we'll do a prevent default, and then we'll focus on the first element.

[00:06:05]
So let's give that a try and see how it went. We'll open up the modal tab to the end. Yes, okay, so now I have tabbed to the cancel and then I hit tab again, and it takes me to the name, and let's see if shift tab takes me to the cancel.

[00:06:19]
So I can kinda hold the tab key and just circle around these things, and that should be good. I find the active element opens up a bunch of really cool features that you can build by preserving their focus. You could do other things, you could get fancy. I think right now you open the modal, it does.

[00:06:37]
Okay, it focuses on the first element. But if you had a more robust custom application, you could unopen, make sure that the user was focused where you'd like them to be, and kind of trapping them in. Also making sure that there are ways for example, you should be able to hit escape to close the modal because if you're keyboard only, you're not gonna be able to click away from it.

[00:06:58]
So just kind of some considerations like that.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 7-Day Free Trial