Website Accessibility, v3

Keyboard-Only & Tabbing

Jon Kuperman
Bloomberg
Website Accessibility, v3

Lesson Description

The "Keyboard-Only & Tabbing" Lesson is part of the full, Website Accessibility, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Jon explains why adding keyboard shortcuts and other navigation features in web applications improves accessibility and provides enhancements for power users. HTML has several keyboard/tab enabled elements by default. The tabindex attribute can make no-focusable elements tab-enabled. Tab trapping is another useful navigation technique to help keyboard users.

Preview
Close

Transcript from the "Keyboard-Only & Tabbing" Lesson

[00:00:00]
>> Speaker 1: Let's keep going on this topic of keyboard-only users, and all the great things that we can do. And here's where I think we get into the most fun engineering tasks for the next little bit of a section, cuz we can build some really cool things for people.

[00:00:12]
So, the idea being, your entire application should be usable with only the keyboard, all of your forms, your buttons, etc. You should have some type of focus indicator to provide a necessary clue as to the currently active item, where you are on the page. And you should consider offering an any kind of shortcuts for keyboard-only users to jump quickly to the main content, which we often call a skip link, and we'll show some cool examples of those.

[00:00:35]
So WebAIM's recommendations here is, when elements receive focus, they don't make a substantial change to the page. So again, like pop up windows or changing keyboard focus or anything like that. Make sure that you don't do anything that could confuse or disorient the user. When a user inputs information or interacts, it doesn't result in substantial changes.

[00:00:55]
So again, we're a little bit just trying to think of good design principles here that, as you tabbing around the page, shouldn't be shifting and moving or anything like that. As you open a modal, it shouldn't necessarily change out the entire background, things like that. And then navigation links that are repeated, they don't change order, so again, this is just a good UX principle.

[00:01:15]
But if you have a set of ten links at the top, let those be the same on every page. Because oftentimes, screen reader users or keyboard-only users will skip the navigation section. So if it's inconsistent, and then they go back to it, and it's different, that can cause confusion.

[00:01:29]
Great, so keyboard shortcuts, these are one of my favorite things to build whenever I work on new websites. Website social networks like Twitter and Facebook and YouTube offer really cool shortcuts. These are great for accessibility purposes, they're great for power users, and they're great for people who like Vim.

[00:01:45]
They're really fun to build and really nice for people to use, so, some examples, if you go to any of your favorite social media websites and hit question mark or shift question mark, you'll get these popups. So I think I took these from like Twitter and Facebook and YouTube, but most websites have these.

[00:02:01]
So you load the page, you hit shift question mark or question mark, and you get this keyboard shortcut. And the idea here is it should have a big list of common actions that you would want to take. I guess maybe a show of hands, how many people have used keyboard shortcuts on popular websites before?

[00:02:15]
All right, Vim users maybe, yeah, cool, so a lot of people don't, I get really addicted to them when I kinda figure it out cuz it's just really fast to hop to the timeline, send up a new message or whatever. Similarly, this is Facebook, so you just go and you hit question mark, and it pops up this big keyboard shortcut window, and then YouTube has a really similar one.

[00:02:34]
So it's just a nice accessibility thing that's there on all your favorite websites, but maybe you haven't noticed before. Skip links, these are another foundational concept is that websites are often structured with a big header, and the header stays the same on every page. And that header is usually full of tabbable items, like links, and if you imagine being a keyboard-only user, every time you go to a new page, you'd have to tab through all 28 of your header links to get to the main content.

[00:03:00]
And so skip links are a concept where if you've just refreshed the page, and you hit Tab for the very first time, they inject a secret extra link into the HTML that's called skip to main content. And if you interact with that, then you jump down into the main container, and if you tab past it, then you can freely use the links like normal.

[00:03:18]
And so, these are really great, they're quite easy to build, but they're very nice for people, and these are very common on news' websites, for example. So if you go to BBC and you load a page, and then right when you've hit refresh for the first time you hit Tab, you'll notice this little skip to content link shows up.

[00:03:34]
This is true on GitHub as well, you load GitHub.com and then hit Tab, and you'll get this skip link kind of embedded in there. And you hit space or click on it or whatever, and it'll jump you to the main bit of content, let you skip right over the navigation.

[00:03:49]
So, the idea with a skip link is pretty easy, you make an anchor, and it should be the first anchor in your list, and it's got the body, skip to main content, or skip. Make sure it's prepended to your website, AKA make sure it's the first tabbable item that there is.

[00:04:05]
Make it visually hidden, use the class that we used before, and then on focus state, make it visually visible, and it's quite easy to do. So yeah, you basically just add an anchor hover, hide it visually, but make sure with your CSS selector that the on focus selector is visual, not hidden, and then it'll show up there.

[00:04:22]
And make sure that the link itself is an internal anchor to your container ID, like a hash anchor to whatever, main, or whatever you call your main container. Cool, so yeah, WebAIM compliance here, links are provided in some way to skip navigation and other page elements that are repeated.

[00:04:38]
So just any structure, it doesn't even need to be visually hidden, it could just be there, your first link could just be skipped to navigation. And then proper structure of a page might be considered sufficient, so here I think it's saying that having a good heading structure of H1S and things like that may well be sufficient without a skip link.

[00:04:57]
Cuz as we saw before, we could use something like the web rotor and just skip through H1S. But if you have a lot of repeated links that are hard to navigate through, a skip link can be a really great way to do it. And also related things, making sure the webpage itself has an informative page title.

[00:05:13]
So that's like the title tag in HTML and that the navigation is logical and intuitive. So again, a lot of these are just kind of good design principles, but the skip link itself is a very fun to build, easy to build and really powerful tool for keyboard only users.

[00:05:28]
Cool, so keeping the story going with tab navigation, we hinted at this a little bit earlier when we did the exercise of building the button with a DIV. But the idea being that you need to be able to use the tab key to navigate to the next tabbable item and shift tab to navigate to the previous tabable item.

[00:05:46]
So this is the way that the web works by default in all major browsers, but we do have some cool control as developers here. So the requirement here is that all page functionality is available using the keyboard. So making sure that there aren't any things that are out of reach for keyboard only users.

[00:06:01]
Suggestions here that you can add shortcut keys, but make sure that they don't go conflict with existing browser and screen reader shortcuts. So the examples here being usually I think we stick to the same set of keys which are largely influenced by vim and other keyboard. Heavy things, so using, what is it?

[00:06:20]
Like H and J to go up and down, things like that, just make sure that you're not binding any helpful keyboard shortcuts to escape caps lock, control, anything that might be necessary for other things. Again, the compliance thing here is that make sure that AAA compliance, everything can be available using the keyboard.

[00:06:40]
But for A compliance, everything can be available using the keyboard, unless it's something that can't be accomplished in any known way. So you can be A and AA compliant, let's say you have a drawing app or something like that. You don't need to make the entire drawing app itself keyboard accessible.

[00:06:56]
You just need to make everything that can be done with a keyboard done with the keyboard. How are we feeling about that? Pretty good? Cool, so what are tabbable elements? So the tabbable elements in HTML are anchors, buttons, inputs, selects, text areas and iframes, so these are things that come with default functionality.

[00:07:14]
They register themselves as tabbable, and then as a user is tabbing or shift tabbing through a website, they can interact with these things. So most of these, or all of these are items where there will be some user input required in some way, whether it's an anchor that a user clicks on or an input that a user enters information, or an iframe that a user hops in between.

[00:07:36]
There's a reason these are tabbable because they mark points where a user would need to interact with them. Just a quick shout out, I really don't care if people use this or not, but if you are making a list of all of your focusable or tabbable elements, and you want to have that in a CSS selector, I have this very simple JavaScript library that just exports a simple string of all tabbable HTML elements.

[00:07:57]
Because while this list has the main ones, there are actually hundreds of sub tabbable elements like input type, emails, or all sorts of things with ARIA attributes or tabbable attributes. And so I have this little open source repository here, jcoop/focusable, and it's literally just a string of every modern tabbable element that you can use in a number of ways when you're building accessibility features.

[00:08:21]
So what if we have an element that we wanna be interactive, but it's not tabbable? And we covered this a little bit with the button before, so there is a tab index attribute that you can add to any element. And so if you take a div, and you add tabIndex 0 to it, then all of a sudden you refresh the page, and you start tabbing through the page, and you will focus on this div, and it'll get a focus state like it was an input, and it will show up, and the screen reader will read it.

[00:08:45]
The screen reader will not read a role assigned to it until you assign an ARIA role, but it will read it and treat it as a focusable interactive element. Has anybody used tabindexes before on their website? Cool, people have, that's great, yeah, really exciting. So tabindex has three values, it has a negative value, which means that the element should be focusable but not reachable through sequential navigation.

[00:09:09]
Meaning, if you think of when you load a page, it basically crawls every tabbable element, and it puts them in a list together, and then as you tab, it goes next. And as you shift tab, it goes previous, a negative value means we still want this. We wanna be able to call like with JavaScript, call, focus on it, but we don't want the user to be able to access it with the keyboard.

[00:09:28]
Maybe a little bit more rarely to use this one, the more common one is 0. So 0 means the element should be focusable, it should be reachable via navigation, and its relative order should be defined where it falls in the dom, basically, right? So if it's the first element, like a div, and you add tabIndex 0 to it, it'll be the first thing there.

[00:09:48]
I realize that wording is a little bit complex, does that make sense though, that 0, tabbable, focusable, and it'll just show up in the order in which it appears in the markup, essentially. And then a positive value means it should be focusable, reachable through the keyboard navigation. But now its relative order is defined by the value of the attribute, kind of like Z index, right?

[00:10:07]
Where the higher it is, the higher it shows up. Okay, so this is possible, this is supported, this is standard, but it is very much not recommended. So the W3C and MDN recommend that you only use 0 and -1, So you can have it focusable and not navigable, or focusable and navigable.

[00:10:25]
But don't use these positive integer values because they can mess with so many different types of navigation, and they can make things very confusing for screen readers. So it is possible it is supported, Just got a big red warning on it to stick with the zeros and the negative ones where possible.

[00:10:43]
I don't think I've ever used a positive value in production, I use the negative one very rarely when I have something that I want to be able to draw focus to later, but isn't really something to be interacted with now. And I use the zero by far the most often to just turn something into a tappable element.

[00:11:00]
Cool, so as we're building these accessibility features, there's a really nice API that's important for a lot of them, which is the document active element. And so on single page applications, I often come up with a lot of different use cases for storing the currently focused element. So one that I'll give you is there's this pretty common design workflow that you have in your app, and it's got a list of things, and you're tabbing through news articles or something like that.

[00:11:28]
Then you interact with something that pops up a modal, like a login modal or like view the article in details modal or something like that. When you close the modal, the ideal experience is that you send the focus right back to where it was before. Or otherwise, the users will have to start at the top again and navigate all the way down.

[00:11:45]
So it's actually really easy to do where when you trigger the modal in JavaScript, before you change anything, you store the currently active element, document an active element. And then when the modal closes, you just call .focus on it, quite simple APIs. So anytime that you're dealing with these page transitions or something pops up and you just wanna make sure that the user remains in their place.

[00:12:09]
I think we've all been there before, you're on a social site, and then you click on something, then you hit the back button, and it takes you back to the top, and you've lost your feed or whatever. This is really easy to solve with code, so on click, store the current active and then on close, call .focus on it, and it takes you right back there, exactly like you would expect.

[00:12:29]
Cool, I think the last concept we talked about skip links and navigation, all this stuff, tabbable elements, is this idea of tab trapping. This is another one that I think these big professional websites almost always do, and as a user you would expect it to be there, but it's not necessarily something that you would think of when building your application.

[00:12:49]
And the idea is best described with a modal pop up, so like a login modal or something like that. You would think that when the modal is popped up and your website is grayed out, that the modal sort of becomes the whole website as far as you're concerned.

[00:13:03]
And therefore, tabbing and shift tabbing should only take you through the tabbable elements in the modal itself, right? Like you shouldn't be like tabbing all the way back into the page, which is grayed out because even though the page is still there and the HTML is still live, we're visually telling yo u that we've grayed out the page and the modal is the only thing important.

[00:13:21]
And so with workflows like this, sometimes it's on us as developers to add a little bit of JavaScript to make sure that the sequential tabbing works in the way that we would expect. Because as far as the browser knows, we still have all of those tabbable elements on the core page itself as well as all of these new ones.

[00:13:37]
And you could quickly get into a situation where you tab down to the submit button, and then you hit tab one more time, and you're somewhere in the grayed out website underneath. And so this is like a common thing that if you use like a CSS component library, they'll almost always have tab trapping built in with their modals.

[00:13:53]
Like, if you were to use Material UI or Bootstrap or some React library, they almost always have this built in. But it is an important thing to consider, especially if you're building your own components, this is expected behavior from users.

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