Skip to content
Wiki
Keyboard
Keyboard Navigation

Keyboard Navigation

Make all functionality available from a keyboard.

WCAG 2.1 (opens in a new tab)

Keyboard Navigation is a subset of WCAG 2.1 for "Keyboard Accessible", and a simple addition to this is to mention that there shouldn't be any keyboard traps.

The crux of this page is that every interactive element should be accessible via keyboard navigation. This means that every interactive element should be focusable, and that the user should be able to navigate through the page using the keyboard.

This is easily tested by tabbing through a web page and checking that every single thing a user could interact with using a mouse can also be interacted with using a keyboard. (With a few minor exceptions noted in the WCAG 2.1.1 guidelines.)

In the example below, try to interact with the middle button using the keyboard. You'll find that it's not possible.

Ways to fix

The example above is a bad example as the button was explicitly removed from the tab order using tabindex="-1".

However that's still a good first fix, ensure that no interactive elements are removed from the tab order.

Other approaches to fixing this for custom components include using native components, adding tabindex="0" to elements when new, non-native interactivity is required, or simply using an existing component library.

Tab index

Preserving the tab order is important, and the tabindex attribute can be used to control this.

There may be plenty of good uses for the tabindex attribute, but for accessibility purposes it will be either used for adding things to the tab order that need to be there using tabindex="0", or removing things from the tab order that shouldn't be there usingtabindex="-1".

Native elements

Instead of trying to be smart and making a custom components out of divs and forgetting to add tab indexes, keyboard events, or other accessibility features, it's often better to use native components.

The example above uses a div styled like a button, but didn't have any tabindex assigned like in the code below, this means it cannot be focused with a keyboard and therefore cannot be interacted with.

Whereas the button element just works. Screen readers announce it correctly, keyboards can focus and interact with it, and it gives you some default goodies like focus indication styles and on click effects for free.

  <div onClick={() => alert("Click!")}>Click me!</div>
  <button onClick={() => alert("Click!")}>Click me!</button>

Component libraries

The issues faced by web developers when trying to come up with a fancy new component are often already solved by existing component libraries. there are many with accessibility built in, and they often come with a lot of customisation options, so it's still possible to make the components look and feel unique.

Libraries such as MUI (opens in a new tab), Chakra UI (opens in a new tab), Radix (opens in a new tab), and Cauldron (opens in a new tab) all have accessibility built in.

While these may miss some complex components, most of these cover a wide array of useful components used in the majority of projects and are a great starting point for any new project.

Preventing Keyboard traps

The other part of this is to ensure that there are no keyboard traps. This means that the user should be able to navigate throughout the page using the keyboard, and not get stuck in any one place.

It may not just be being stuck in one place, but being stuck within a loop that cannot be escaped, such as being stuck in an iframe, or in a grid or table that doesn't allow the user to navigate out of it.

The fix for this is just to provide a way to escape, such as a close button, or a keyboard shortcut like escape that is made obvious somewhere as the way to leave the component.

References