CodePark/ questions / Accessible widgets
START PRACTICINGPRACTICE
Frontend question · Accessibility › Accessible widgets

How do you build an accessible tabs component? Give the roles, attributes and keyboard behaviour.

<div role="tablist" aria-label="Account settings">
  <button role="tab" id="t1" aria-selected="true"
    aria-controls="p1">Profile</button>
  <button role="tab" id="t2" aria-selected="false"
    aria-controls="p2" tabindex="-1">Billing</button>
</div>
<div role="tabpanel" id="p1" aria-labelledby="t1" tabindex="0">…</div>
<div role="tabpanel" id="p2" aria-labelledby="t2" tabindex="0" hidden>…</div>

Tabs use three roles: tablist, tab and tabpanel. They follow the W3C ARIA Authoring Practices pattern.

Roles and attributes:

  • The wrapper has role="tablist" and a name, such as aria-label="Account settings".
  • Each tab is a <button role="tab">. The active one has aria-selected="true", and the others false.
  • Each tab points to its panel with aria-controls.
  • Each panel has role="tabpanel" and aria-labelledby pointing back to its tab. Hidden panels get hidden.
  • A panel gets tabindex="0" if it has nothing focusable inside, so keyboard users can reach its content.

Keyboard:

  • The tab list is one Tab stop, using a roving tabindex. Only the active tab has tabindex="0".
  • Left and Right arrows move between tabs. Home and End go to the first and last tab.
  • The next Tab moves into the active panel.

Tabs can switch the panel as soon as a tab gets focus (automatic activation). Or they can switch only on Enter or Space (manual activation). Choose manual when loading a panel is slow.

  • Tabs use role="tablist", role="tab" and role="tabpanel".
  • The active tab has aria-selected="true", and tabs and panels link with aria-controls and aria-labelledby.
  • The tab list is one Tab stop, and arrow keys move between tabs.
  • Home and End jump to the first and last tab, and Tab moves into the panel.
  • Activation can be automatic on focus or manual on Enter or Space.