New Element Proposals: tablist
, tab
, and tabpanel
Introduction
“The
details
element is needed to provide an accessible way of reflecting a common application widget in HTML-based applications without requiring authors to use extensive scripting, ARIA, and platform-specific CSS to get the same effect.”
The same could be said about a tab list.
In this demo, I have used Web Components technology to define custom elements custom-tablist
, custom-tab
, and custom-tabpanel
.
The elements are given a set of semantics (ARIA attributes), behaviors (event listeners), and styles (CSS).
If HTML authors currently want to use such a widget, they must define these features each and every time.
The obvious disadvantage is that authors will not likely be consistent in implementation due to the uncountably many ways to do so.
Furthermore, author implementation will vary with browser support: as of , only Google Chrome supports Web Components.
I have drafted specifications for proposed tablist
, tab
, and tabpanel
elements below.
If such elments made their way into the HTML Standard and were implemented by browsers,
authors could simply write the HTML elements and expect them to behave as specified.
(Just like <details>
.)
Specifications
Warning: This is not a real specification. Draft requesting review by WHATWG.
The tablist
element
- Categories:
-
- Flow Content
- Sectioning Root
- If the element’s children include at least one tab-panel pair: Interactive Content
- If the element’s children include at least one tab-panel pair: Palpable Content
- Contexts in which this element can be used:
- Where Flow Content is expected.
- Content Model:
- Zero or more implicit pairs, each consisting of
exactly one
tab
element followed by exactly onetabpanel
element, optionally intermixed with script-supporting elements. - Tag omission in text/html:
- Neither tag is omissible.
- Content Attributes:
- Global attributes
- Allowed ARIA role attribute values:
tablist
- Allowed ARIA state and property attributes:
- Global
aria-*
attributes - Any
aria-*
attributes applicable to the allowed roles - DOM Interface:
-
interface CustomTablist : HTMLElement {};
A tablist
element represents a tab list:
a list of tab-panel pairs, wherein all tabs and at most one panel are exposed to the user.
When the user selects a tab, its corresponding panel becomes exposed and all other panels become hidden.
Note:
An empty tablist
element is valid; in this case no tabs or panels are exposed.
User agents must add the tablist
element’s focusable children to the tab sequence of a page, in a manner defined by the algorithm below:
- Let the page’s tab sequence be identified by P.
- Remove all focusable descendants of the
tablist
from P. - Create a new empty tab sequence T.
- For each tab-panel pair in the
tablist
, perform the following subroutine: - Inject T into P, between
the last focusable element preceding the
tablist
and the first focusable element following thetablist
.
This algorithm must be re-run each time a new tab
element is selected.
The tab
element
- Categories:
- None
- Contexts in which this element can be used:
- As a child of a
tablist
element: directly before atabpanel
element. - Content Model:
- Either Phrasing Content, or exactly one element of Heading Content.
- Tag omission in text/html:
- A
tab
element’s end tag can be omitted if the element is immediately followed by atabpanel
element. - Content Attributes:
- Global attributes
- Allowed ARIA role attribute values:
tab
button
- Allowed ARIA state and property attributes:
- Global
aria-*
attributes - Any
aria-*
attributes applicable to the allowed roles - DOM Interface:
-
interface CustomTab : HTMLElement {};
A tab
element represents a tab in a tab list.
The corresponding panel
of a tab
element is the adjacent tabpanel
sibling that follows it.
The tab labels its corresponding panel.
All tabs in a tab list must always be exposed to the user.
When a tab is selected, its corresponding panel must be expanded, and when a tab is not selected, its corresponding panel must be collapsed. The user agent should allow the user to select a tab. No more than one tab may be selected at a time.
The tabpanel
element
- Categories:
- None
- Contexts in which this element can be used:
- As a child of a
tablist
element: directly after atab
element. - Content Model:
- Flow Content
- Tag omission in text/html:
- A
tabpanel
element’s end tag can be omitted if the element is immediately followed by atab
element, or if there is no more content in the parent element. - Content Attributes:
- Global attributes
open
- Whether the panel is exposed- Allowed ARIA role attribute values:
tabpanel
- Any role that supports
aria-expanded
- Allowed ARIA state and property attributes:
- Global
aria-*
attributes - Any
aria-*
attributes applicable to the allowed roles - DOM Interface:
-
interface CustomTabpanel : HTMLElement { attribute boolean open; };
A tabpanel
element represents a panel in a tab list.
The corresponding tab
of a panel
element is the adjacent tab
sibling that precedes it.
The panel is labeled by its corresponding tab.
No more than one panel in a tablist should be exposed to the user.
The open
content attribute is a boolean attribute
whose presence indicates whether or not the content of the panel is to be exposed to the user.
A panel is called expanded when its open
attribute is present,
and collapsed otherwise.
When the element is created,
if the open
attribute is absent, the information should be hidden;
if the attribute is present, that information should be shown.
Subsequently, if the attribute is removed, then the information should be hidden;
if the attribute is added, the information should be shown.
The user agent should allow the user to request that the panel’s contents be shown or hidden.
To honor a request for the contents to be shown,
the user agent must set the open
attribute on the element to the empty string.
To honor a request for the information to be hidden,
the user agent must remove the open
attribute from the element.
A tablist
element must have
no more than one child tabpanel
element with its open
attribute set.
If no child tabpanel
elements have the open
attribute present,
the user agent should set that attribute on the first tabpanel
element child,
with the empty string as its value.
Any time the user agent sets the open
attribute on a tabpanel
child of tablist
,
it must remove the open
attribute from all other sibling tabpanel
elements.
The open
IDL attribute
must reflect the open
content attribute.
Suggested User Interaction
As stated above, the user agent should allow the user to request that a panel’s contents be shown or hidden, and it should show at most one panel in a tab list at all times. This section describes possible implementations of these axioms.
At any time, the user may select a tab by clicking or tapping it.
The tabindex
attribute of all tab
elements should be set to 0
,
so that keyboard users can access them.
The Tab key may move the focus to these elements in the standard tab sequence order, and
Shift + Tab may move the focus in reverse order.
When a selected tab has focus, subsequent keystrokes of the Tab key should move the focus to within the expanded panel, to any focusable elements such as any links or form controls. When the focus has reached the end of the panel, it should then proceed to the next tab in the tab list, or if there is none, out of the tab list.
When an unselected tab has focus, its corresponding panel is not exposed to the user. Thus the Tab key should move the focus not to any elements within the collapsed panel, but rather to subsequent tabs in the tab list, or if there are none, out of the tab list.
When any tab (selected or not) has focus, the user may press the Space key (the spacebar) to select it. The spacebar is probably a better choice than Enter, as the latter typically activates links and leads the user away from the page. To activate a focused tab, it is best to use the same key that activates form controls.
When any tab (selected or not) has focus, the user may press any arrow keys (Up, Down, Left, Right) to select another tab and give it focus. When Down or Right is pressed, the next tab in the tab list should be selected and receive focus, and when Up or Left is pressed, the previous tab should be selected and receive focus. These keybindings allow for both vertical and horizontal layouts of tabs. If the user reaches the end or the beginning of the list of tabs, the selection should wrap around to the other side of the list.
Note:
The user agent should set directional key bindings based on writing mode and direction,
and whether or not the tab list is styled accordingly.
For example, in a right-to-left direction (dir="rtl"
),
the user agent should switch the behavior of the Left and Right keys,
but only if the tabs were also displayed from right to left.
If, however, the dir="rtl"
attribute were specified, but the tabs were still displayed from left to right,
the directional keys should retain their original functionality.
Lastly, the user agent should allow the user to use the Home and End keys to move the focus to the first tab and last tab, respectively, and select it.
Key | Function |
---|---|
Tab | Respects the tab sequence of the page. See tablist tab sequence for details.
When the tab key brings focus to a tab element, it does not necessarily select it. |
Space | Selects the tab. |
Down / Right |
|
Up / Left |
|
Home | Moves focus to the first tab and selects it. |
End | Moves focus to the last tab and selects it. |
Suggested Presentation
This section provides suggestions for default styling of the tablist
element and its children.
The selected tab in a tab list
should be styled differently from unselected tabs in the same tab list.
This meets
Level
AAA of §2.4.8 (Location) of WCAG 2.0:
Information about
the user’s location within a set of Web pages is available.
Within a tablist
element,
user agents should display all the tab
children together in a single track,
with the expanded tabpanel
element on a separate track.
Three popular layouts are described below, but user agents are not limited to these.
- Horizontal Tabs
Tabs may be laid out in a single row. If this is the case, tabs should be laid out in the inline direction (from left to right, or, if the text direction is
rtl
, right to left instead). The expanded panel may appear either below or above the tab row, and the tab widths could be evenly divided into the panel width.- Vertical Tabs
Tabs may be laid out in a single column, preferrably in the block direction (top to bottom in most writing modes). The expanded panel may appear either to the left or to the right of the tab column, and the panel height could be set to the total sum of the heights of the tabs.
- Mobile Devices
Small screens might not have enough real estate to be able to display one track of tabs with another track for the panel. Therefore, it is advantageous to lay out the tabs and panel together into one track, similarly to an accordion component (the difference being that in an accordion it is possible to expand more than one panel at a time). Rather than grouping the tabs separately from the panel, the user agent could display the expanded panel directly after its corresponding tab.