Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. Accessibility
  3. ARIA
  4. ARIA reference
  5. Roles
  6. tab

ARIA: tab role

The ARIAtab role indicates an interactive element inside atablist that, when activated, displays its associatedtabpanel.

html
<button role="tab" aria-selected="true" aria-controls="tabpanel-id">  Tab label</button>

Description

An element with thetab role controls the visibility of an associated element with thetabpanel role. The common user experience pattern is a group of visual tabs above, or to the side of, a content area, and selecting a different tab changes the content and makes the selected tab more prominent than the other tabs.

Elements with the roletabmust either be a child of an element with thetablist role, or have theirid as part of thearia-owns property of atablist. This combination identifies to assistive technology that the element is part of a group of related elements. Some assistive technology will provide a count of the number oftab role elements inside atablist, and inform users of whichtab they currently have targeted. Further, an element with thetab roleshould contain thearia-controls property identifying a correspondingtabpanel (that has atabpanel role) by that element'sid. When an element with thetabpanel role has focus, or a child of it has focus, that indicates that the connected element with thetab role is the active tab in atablist.

When elements with thetab role are selected or active they should have theiraria-selected attribute set totrue. Otherwise, theiraria-selected attribute should be set tofalse. When a single-selectabletablist is selected or active, thehidden attribute of the other tabpanels should be set to true until the user selects the tab associated with that tabpanel. When a multi-selectabletablist is selected or active, its corresponding controlledtabpanel should have itsaria-expanded attribute set totrue and itshidden attribute set tofalse, otherwise the reverse.

All descendants are presentational

There are some types of user interface components that, when represented in a platform accessibility API, can only contain text. Accessibility APIs do not have a way of representing semantic elements contained in atab. To deal with this limitation, browsers, automatically apply rolepresentation to all descendant elements of anytab element as it is a role that does not support semantic children.

For example, consider the followingtab element, which contains a heading.

html
<div role="tab"><h3>Title of my tab</h3></div>

Because descendants oftab are presentational, the following code is equivalent:

html
<div role="tab"><h3 role="presentation">Title of my tab</h3></div>

From the assistive technology user's perspective, the heading does not exist since the previous code snippets are equivalent to the following in theaccessibility tree:

html
<div role="tab">Title of my tab</div>

Associated roles and attributes

aria-selected

boolean

aria-controls

id of element withtabpanel role

id

content

Keyboard interactions

KeyAction
TabWhen focus is outside of thetablist moves focus to the active tab. If focus is on the active tab moves focus to the next element in the keyboard focus order, ideally the active tab's associatedtabpanel.
Focuses and optionally activates the next tab in the tab list. If the current tab is the last tab in the tab list it activates the first tab.
Focuses and optionally activates the previous tab in the tab list. If the current tab is the first tab in the tab list it activates the last tab.
Enter/SpaceWhen a tab has focus, activates the tab, causing its associated panel to be displayed.
HomeFocuses and optionally activates the first tab in the tab list.
EndFocuses and optionally activates the last tab in the tab list.
DeleteWhen allowed removes the currently selected tab from the tab list.

Required JavaScript features

Note:While there are ways to build tab-like functionality without JavaScript, there is no substitute combination using only HTML and CSS that will provide the same set of functionality that's required above for accessible tabs with content.

Example

This example combines the roletab withtablist and elements withtabpanel to create an interactive group of tabbed content. Here we are enclosing our group of content in adiv, with ourtablist having anaria-label which labels it for assistive technology. Eachtab is abutton with the attributes previously mentioned. The firsttab has bothtabindex="0" andaria-selected="true" applied. These two attributes must always be coordinated as such—so when another tab is selected, it will then havetabindex="0" andaria-selected="true" applied. All unselected tabs must havearia-selected="false" andtabindex="-1".

All of thetabpanel elements havetabindex="0" to make them tabbable, and all but the currently active one have thehidden attribute. Thehidden attribute will be removed when atabpanel becomes visible with JavaScript.

Note:Settingtabindex on the tab panel is unnecessary if the first element in the tab panel is focusable (such as a link), because tabbing to the link will also start reading the panel's content. However, if there are any panels in the set whose first content element is not focusable, then all tabpanel elements in a tab set should be focusable, so that screen reader users can navigate to the panel content consistently.

html
<div>  <div role="tablist" aria-label="Select your operating system">    <button      role="tab"      aria-selected="true"      aria-controls="panel-1"           tabindex="0">      Windows    </button>    <button      role="tab"      aria-selected="false"      aria-controls="panel-2"           tabindex="-1">      macOS    </button>    <button      role="tab"      aria-selected="false"      aria-controls="panel-3"           tabindex="-1">      Linux    </button>  </div>  <div>    <div role="tabpanel" tabindex="0" aria-labelledby="tab-1">      <p>How to run this application on Windows</p>    </div>    <div           role="tabpanel"      tabindex="0"      aria-labelledby="tab-2"      hidden>      <p>How to run this application on macOS</p>    </div>    <div           role="tabpanel"      tabindex="0"      aria-labelledby="tab-3"      hidden>      <p>How to run this application on Linux</p>    </div>  </div></div>

There is some basic styling applied that restyles the buttons and changes thez-index oftab elements to give the illusion of it connecting to thetabpanel for active elements, and the illusion that inactive elements are behind the activetabpanel. You need to clearly distinguish the active tab from the inactive tabs, such as thicker borders or larger size.

.tabs {  padding: 1em;}[role="tablist"] {  margin-bottom: -1px;}[role="tab"] {  position: relative;  z-index: 1;  background: white;  border-radius: 5px 5px 0 0;  border: 1px solid grey;  border-bottom: 0;  padding: 0.2em;}[role="tab"][aria-selected="true"] {  z-index: 3;  border-top-width: 4px;}[role="tabpanel"] {  position: relative;  padding: 0 0.5em 0.5em 0.7em;  border: 1px solid grey;  border-radius: 0 0 5px 5px;  background: white;  z-index: 2;}[role="tabpanel"]:focus {  border-color: #356fb3;  outline: 1px solid #356fb3;}

The user interaction is handled with JavaScript. We first get references to ourtablist, all thetab elements inside it, the container of ourtabpanel elements, and all thetabpanel elements inside that container. This is based on some assumptions about the structure of our HTML, so if you change the structure, you will need to change this code. If you have multiple tabbed interfaces on a page, you can wrap this code in a function and passtabsContainer as an argument.

js
const tabsContainer = document.querySelector(".tabs");const tabList = tabsContainer.querySelector(':scope > [role="tablist"]');const tabs = Array.from(tabList.querySelectorAll(':scope > [role="tab"]'));const tabPanelsContainer = tabsContainer.querySelector(":scope > .tab-panels");const tabPanels = Array.from(  tabPanelsContainer.querySelectorAll(':scope > [role="tabpanel"]'),);

For keyboard interactions, we listen for thekeydown event on thetablist. In this demo, we chose to not activate thetab when the user navigates with the arrow keys, but instead only move focus. If you want to display thetab when it receives focus, you can call theshowTab() function (defined later) instead of just callingfocus() on the new tab.

js
tabList.addEventListener("keydown", (e) => {  const currentTab = e.target;  const currentIndex = tabs.indexOf(currentTab);  if (currentIndex === -1) return; // Exit if the focused element is not a tab  let newIndex = 0;  switch (e.key) {    case "ArrowRight":      newIndex = (currentIndex + 1) % tabs.length;      break;    case "ArrowLeft":      newIndex = (currentIndex - 1 + tabs.length) % tabs.length;      break;    case "Home":      newIndex = 0;      break;    case "End":      newIndex = tabs.length - 1;      break;    default:      return; // Exit if the key is not recognized  }  e.preventDefault();  e.stopPropagation();  tabs[newIndex].focus();});

The tab panel is only activated either by pressingEnter orSpace while atab has focus, or by clicking on atab. We first define a functionshowTab() that takes in thetab element to be shown.

js
function showTab(targetTab) {  // Unselect other tabs and set this tab as selected  for (const tab of tabs) {    if (tab === targetTab) continue;    tab.setAttribute("aria-selected", false);    tab.tabIndex = -1;  }  targetTab.setAttribute("aria-selected", true);  targetTab.tabIndex = 0;  // Hide other tab panels and show the selected panel  const targetTabPanel = document.getElementById(    targetTab.getAttribute("aria-controls"),  );  for (const panel of tabPanels) {    if (panel === targetTabPanel) continue;    panel.hidden = true;  }  targetTabPanel.hidden = false;}

Now we can call this function either on aclick event or on akeydown event.

js
tabs.forEach((tab) => {  tab.addEventListener("click", (e) => {    showTab(e.target);  });  tab.addEventListener("keydown", (e) => {    if (e.key === "Enter" || e.key === " ") {      e.preventDefault();      e.stopPropagation();      showTab(e.target);    }  });});

Best practices

It is recommended to use a<button> element with the roletab for their built-in functional and accessible features instead, as opposed to needing to add them yourself. For controlling tab key functionality for elements with the roletab, it is recommended to set all non-active elements totabindex="-1", and to set the active element totabindex="0".

Precedence order

What are the related properties, and in what order will this attribute or property be read, which property will take precedence over this one, and which property will be overwritten.

Specifications

Specification
Accessible Rich Internet Applications (WAI-ARIA)
# tab
Unknown specification

See also

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2026 Movatter.jp