Skip to main content

Keyboard Navigation and Semantic HTML

Getting keyboard navigation right not only assists people with motor and visual disabilities, but also power-users! It's a must have on any website and this lesson will introduce you to how you can use your keyboard to navigate, and the HTML elements we can use with keyboard support built in.

1a: How does keyboard navigation work?

There are many elements within HTML. Most commonly seen are elements such as "a" (a is for anchor, AKA links), "button", "select" etc. These are just some of the elements which support keyboard interactions.

Notice how if you press your tab key to navigate forward or shift+tab to navigate backward, when navigating to the button below it will receive a border around it. That border indicates that it is in a "focus" state.

Pressing the "Enter" or "Space" key on the button is the equivalent of clicking it. Try doing that to the button.

Now let's interact with the select element. Use tab or shift + tab as before to focus it. But once focused, you can navigate its options with the arrow keys. Navigate to "Spongebob" and press the Enter or Space key.

These elements are designed to handle keyboard navigation, which is very convenient for us as developers. This leads us to an important realization: using semantically correct HTML elements gets us most of the way there when it comes to accessibility.

1b: Semantic HTML > Custom Roles and Attributes

There are some cases where we want to add additional styles or functionality that an element does not offer. Let’s take the select element as an example (Fun fact: customizable select elements will be implemented in the near future). By default it has a very bare and simple style. Let's walk through building our own. We'll be adding ARIA roles and attributes to enhance the accessibility of our new custom select. ARIA stands for Accessible Rich Internet Applications.

    
      <div role='combobox' aria-expanded='false' aria-haspopup='listbox' tabindex='0' aria-labelledby='select-label'>
	    <span id='select-label'>Choose an option</span>
	  </div>
    
  

Explanation of the Attributes

  1. role='combobox'

    Indicates that the element acts as an input element that controls another element such as a listbox. In other words, this element will have a popup with some options that we can select from.

  2. aria-expanded='false'

    Specifies whether the element is expanded (true) or collapsed (false). Update this dynamically when the element opens or closes.

  3. aria-haspopup='listbox'

    Indicates that the element will display a popup listbox (this will be the dropdown that contains our options).

  4. tabindex='0'

    Makes the div focusable by keyboard.

  5. aria-labelledby='select-label'

    This will make the element with the id "select-label" ("span" in this case) act as a label which will be read out to screen readers. The label text is "Choose an option" in this example.

That was exhausting… All of this just to emulate what was already there in the select element, and it's not even functional yet. Now you can see why it is best to avoid custom implementations like this as much as possible. Using semantic HTML isn't just good practice — it's one of the easiest ways to boost accessibility out of the box.

Test Yourself

Who benefits from accessible web applications?
What do you use to add accessibility to an element?
What does aria-labelledby do?