Skip to content

Date: 19 Oct 2016

Accessible Tabs

When making any complex component for a web page a number of steps are required to make it accessible to disabled people. I find it helpful to reduce things to a simple list of instructions.

A list format is particularly useful when your audience consists of professional web developers who can be expected to know HTML, CSS and JavaScript. If your audience already know why accessibility is necessary in a website, and know the fundamentals of how to program for it, and even better if they are comfortable using ARIA, then a list of steps to perform is often the easiest presentation for them to work from. They can just work down the list implementing each step, knowing they won't overlook anything.

Tab sets are a good example of this. Tabs are ubiquitous in today's web but they are all too frequently highly inaccessible to users of assistive technology, such as screen and Braille readers for the blind. So let's consider the list of steps required to make a tab set accessible.

Who Are We Helping?

As with any complex interactive component, the two groups of user to bear in mind most, when creating tab sets, are:

  1. keyboard-only users (those who, due to some disability, cannot easily use a mouse), and
  2. users of assistive technology. Screen readers for the blind are the most well known of assistive devices. They are also the devices most usually used when assessing a website for accessibility.

We use a lot of ARIA for tab sets. Just remember that ARIA does not affect the appearance or behaviour on-screen, for sighted people (not even for keyboard-only users). Web browsers ignore ARIA except for the sole purpose of passing it through to the accessibility API - the interface for assistive technology devices such as screen readers for the blind. ARIA won't, for instance, get rid of the list bullets on the tabs. You must do that in the CSS. But it will cause a screen reader to tell its user when a tab is opened.

W3C's WAI-ARIA provides the instructions on how to create a tab set, including the ARIA needed and the keys to operate it.

The HTML Structure

A set of tabs can be created without complex frameworks or libraries. It is made up as follows:

  • The tabs should be an unordered list of links using <ul> and <li>.
  • Each list item contains an <a> link to hold the tab label.
  • Each link's href attribute targets a container (normally a <div> or <section>) of content following the tab list.
  • Only one tab panel can show at a time. Initially this will usually be the first tab.

The list lets blind screen and Braille reader users know it is a related set of links, and most readers will tell them, up front, how many tabs they will find.

If you are still using HTML4 or (accessibility isn't choosy) XHTML, you can replace those sections by divs.

Now Make it Accessible

The steps to make a tab set accessible are:

  1. Give the ARIA role of "tablist" to the <ul> list of tab links.
  2. Give the ARIA role of "tab" to each of the links in the tab list.
  3. Give the ARIA role of "tabpanel" to each of the containers of panel content.
  4. Add an aria-controls attribute to each tab link, pointing it to the id of the container of its associated panel. This tells assistive technology where to find the related tab panel.
  5. Add an aria-selected attribute to each tab link, set to "true" on the currently selected tab, and "false" on all the others. Change these values by JavaScript each time a new tab is selected.
  6. Add a tabindex to each tab link, value 0 for the currently selected tab and -1 for the others, so that only the current tab will be reached by the Tab key.
  7. Use CSS display:none to hide the non-selected panels from all users including assistive technology users.
  8. Give each panel's container an aria-labelledby attribute targeting either the main heading at the top of the tab panel, if there is one, or else the tab link itself. This will then be announced by screen readers as the tab panel is displayed.
  9. Any headings in the tab panels should use the HTML heading elements, and should continue the hierarchy established in the page prior to the tab set. For instance, if the tab set is logically part of the content under an <h2> heading in the page, then the first heading found inside each of the tab panels will be an <h3>, and any subheadings belonging to that will be <h4>, and so on.

The result of all this is:

<ul role="tablist">
  <li role="presentation">
      <a role="tab" href="javascript:void(0);"  onclick="showPanel(1)"; tabindex="0"  aria-selected="true" aria-controls="panel1" id="tab1">Tab 1</a>
  <li role="presentation">
      <a role="tab" href="javascript:void(0);"  onclick="showPanel(2)"; tabindex="-1" aria-selected="false" aria-controls="panel2" id="tab2">Tab 2</a>
  <li role="presentation">
      <a role="tab" href="javascript:void(0);"  onclick="showPanel(3)"; tabindex="-1" aria-selected="false" aria-controls="panel3" id="tab3">Tab 3</a>
<section id="panel1" role="tabpanel" style="display:block">...[panel content]...</section>
<section id="panel2" role="tabpanel" style="display:none">...[panel content]...</section>
<section id="panel3" role="tabpanel" style="display:none">...[panel content]...</section>


The reasons for some of the items of markup are shown here (actually in a tabset created using the above code!):

Why the tab roles? The ARIA role attribute of tab allows screen and Braille readers to work in a specific way for these components, following the WAI_ARIA instruction. And they announce the tabs as "tab" to let the user know. Though some of their users initially do not know how these components work in their reader or tool, tabs are so widespread that the more the tab role itself is used, the more quickly are assistive technology users learning how to operate them. Standardisation helps everyone.

Sighted people can easily see how tabs work if they are well designed visually, but blind people need the announcement by their readers that they have reached a tab set. They then know that, if they follow the tab links, they will later be able to tab out of the set and still be in the same region of the page - unlike ordinary in-page links which, if followed, may take them to a far away place on the page, missing all the content in between.

NB: The href attribute in the link needs to be javascript:void(0); to avoid the screen jumping around when tabs are clicked.

The keys to Use

The standard keys for a tab set must be set up in the JavaScript. They are:

ActionKeys to use
To move to the next tab link in the set down or right arrow
To move to the previous tab link in the set up or left arrow
Display the current tab's panel if not already shown Enter/Return or spacebar
  1. To move into the set, landing on the currently selected tab. (If no tab is selected go to the first one.)
  2. If on a selected tab, move to the first instructive item in that tab's panel.
  3. If no more interactive items in the panel, move out of the tab set to the next following interactive item.
Tab (or Shift+Tab if going back up the page)

Notice that this choice of keys, and the uses they have, is broadly the same as for HTML radio buttons (and checkboxes too with the exception of the Tab key behaviour). This makes sense as tabs and radio buttons have a similar structure: they are both lists of items only one of which can be selected at any given moment. One of the concepts of the WCAG is to keep similar things working the same way; it helps all users, but particularly some groups of disabled people. Having tab sets and other interactive components use the same keys as logically similar HTML elements means keyboard-only users, for instance, do not have to learn new key commands for every different website and every component on a website.

Both the down and right arrow keys should do the same thing regardless of whether the tabs are horizontally or vertically displayed on screen, because a blind person does not know the orientation. When the arrow keys reach the end of the set of tabs, they should move out of the set to the next item before or after the tabs. At this point many screen readers will announce the start or end of the list, as appropriate, so the user knows they have reached the end.

This behaviour is defined in WAI-ARIA Authoring Practices Guide.

The JavaScript

  • Every time a click, or press of the Enter, Return or spacebar keys, occurs when a tab is in focus do the following:
    1. toggle the aria-selected attribute to "true" or "false" for each panel
    2. toggle the CSS display property between "block" and "none" for each panel
  • And on .onkeydown(), check for key values of 37 and 38 (left and up arrows) and 39 and 40 (right and down), and use .focus() to move focus to the next or previous tab.

Other design patterns

As always, it is possible to construct this component solely out of div elements, instead of list and link elements. Sadly, many JavaScript and other libraries do this. There is a scripting overhead to this however, since divs do not possess any default events, and do not accept focus or show a focus outline (not that the default focus outline in any of the browsers is the slightest use to anyone with even moderate vision impairment - so a good focus indicator should be added to everything anyway!). These must all be added, including tabindex="0" to put the tabs in focus. I have even seen tabs created using buttons; these by default react to both the Enter/Return keys and spacebar, so neither of those event handlers need to be added.

Another common pattern is to omit the link elements and use just the <li> elements for the tabs with, of course, the ARIA role of tab.

Backward compatibility

Some designs for tab sets advise use of CSS selectors like li[aria-selected='true']. Unfortuantely IE versions prior to IE10 do not understand selectors of this nature, so more backwardly compatible selectors are needed.


Following the WAI-ARIA standard will mean that your tab sets are not only accessible, but will also behave the same way, using the same key operations, as the majority of well designed tab sets throughout the web. This will help disabled people everywhere, and contribute to your website being compliant with industry standards and the WCAG.

By Guy Hickling

I would welcome your thoughts on this subject...

Please speak your heart here:-

- No need to prove you're a human being. I'll just take your word for it.

All content on this site is the copyright of the author