<u-tabs>
<u-tabs>
is not a native HTML element, but follows ARIA authoring practices for tabs. It lets you navigate between groups of information that appear in the same context.
Quick intro:
- Use
<u-tabs>
to group all tabbing-elements - Use
<u-tablist>
around multiple<u-tab>
direct children - these are the labels - Use
<u-tab aria-selected="true">
to set the open tab (defaults to first tab) - Use
<u-tab aria-controls="id-of-panel">
if you need panels outside<u-tabs>
- Use
<u-tabpanel>
s after<u-tablist>
- these hide/show content of related<u-tab>
- ARIA Authoring Practices Guide Docs: Tabs
Example
<u-tabs> <u-tablist> <u-tab>Tab 1</u-tab> <u-tab>Tab 2</u-tab> <u-tab>Tab 3</u-tab> </u-tablist> <u-tabpanel>Panel 1 with <a href="#">link</a></u-tabpanel> <u-tabpanel>Panel 2 with <a href="#">link</a></u-tabpanel> <u-tabpanel>Panel 3 with <a href="#">link</a></u-tabpanel> </u-tabs> <style> /* Styling just for example: */ u-tab { padding: .5em } u-tab[aria-selected="true"] { border-bottom: 4px solid } u-tabpanel { padding: 1em; border: 1px solid } </style>
Install
bash
npm add -S @u-elements/u-tabs
bash
pnpm add -S @u-elements/u-tabs
bash
yarn add -S @u-elements/u-tabs
bash
bun add -S @u-elements/u-tabs
html
<script type="module" src="https://unpkg.com/@u-elements/u-tabs@latest/dist/u-tabs.js"></script>
Attributes and props
<u-tabs>
- Attributes: all global HTML attributes such as
id
,class
,data-
- DOM interface:
UHTMLTabsElement
extendsHTMLElement
UHTMLTabsElement.tabList
returns the containedUHTMLTabListElement
UHTMLTabsElement.selectedIndex
sets or gets anumber
reflecting the index of the first selected<u-tab>
element. Will ignore invalid indexes.UHTMLTabsElement.tabs
returns aNodeListOf<UHTMLTabElement>
UHTMLTabsElement.panels
returns aNodeListOf<UHTMLTabPanelElement>
<u-tablist>
- Attributes: all global HTML attributes such as
id
,class
,data-
- DOM interface:
UHTMLTabListElement
extendsHTMLElement
UHTMLTabListElement.tabsElement
returns the parentUHTMLTabsElement
UHTMLTabsElement.selectedIndex
sets or gets anumber
reflecting the index of the first selected<u-tab>
element. Will ignore invalid indexes.UHTMLTabsElement.tabs
returns aNodeListOf<UHTMLTabElement>
<u-tab>
- Attributes: all global HTML attributes such as
id
,class
,data-
aria-selected
can contain"true"
or"false"
to set the currently selected tabaria-controls
can contain ID the<u-tabpanel>
to control
- DOM interface:
UHTMLTabElement
extendsHTMLElement
UHTMLTabElement.tabsElement
returns the parentUHTMLTabsElement
UHTMLTabElement.selected
sets or getstrue
orfalse
, indicating whether this tab is currently selectedUHTMLTabElement.index
returns anumber
representing the position/index within the list of tabsUHTMLTabElement.panel
returns the associatedUHTMLTabPanelElement
<u-tabpanel>
- Attributes: all global HTML attributes such as
id
,class
,data-
- DOM interface:
UHTMLTabPanelElement
extendsHTMLElement
UHTMLTabPanelElement.tabsElement
returns the parentUHTMLTabsElement
UHTMLTabPanelElement.tabs
returns a associatedNodeListOf<UHTMLTabElement>
Events
No custom events beyond the usual events supported by HTML elements. Tabbing triggers a click
(both with mouse and keyboard) so listen for this to check for tab change:
js
document.addEventListener('click', ({ target }) => {
const tab = target instanceof Element && target.closest('u-tab');
if (tab) {
console.log('changed to tab:', tab);
}
})
Styling
<u-tabs>
, <u-tablist>
and <u-tabpanel>
renders as display: block
, while <u-tab>
renders as display: inline-block
.
Styling the tab state
<u-tab>
automatically gets a aria-selected="true"
or aria-selected="false"
attribute, which can be utilized for styling:
css
.my-tab[aria-selected="true"] {
/* Your active tab styling here */
}
.my-tab[aria-selected="false"] {
/* Your inactive tab styling here */
}
Styling example: Scrolling tablist
<style> .my-tablist-scrolls { display: flex; overflow: auto; white-space: nowrap; } </style> <u-tabs> <u-tablist class="my-tablist-scrolls"> <u-tab>Tab 1</u-tab><u-tab>Tab 2</u-tab><u-tab>Tab 3</u-tab><u-tab>Tab 4</u-tab><u-tab>Tab 5</u-tab><u-tab>Tab 6</u-tab><u-tab>Tab 7</u-tab> </u-tablist> <u-tabpanel>Panel 1</u-tabpanel> </u-tabs>
Styling example: Wrapping tablist
<style> .my-tablist-wrapps { display: flex; flex-wrap: wrap; } </style> <u-tabs> <u-tablist class="my-tablist-wrapps"> <u-tab>Tab 1</u-tab><u-tab>Tab 2</u-tab><u-tab>Tab 3</u-tab><u-tab>Tab 4</u-tab><u-tab>Tab 5</u-tab><u-tab>Tab 6</u-tab><u-tab>Tab 7</u-tab> </u-tablist> <u-tabpanel>Panel 1</u-tabpanel> </u-tabs>
Accessibility
Screen reader | <u-tabs> |
---|---|
VoiceOver (Mac) + Chrome | ✅ |
VoiceOver (Mac) + Edge | ✅ |
VoiceOver (Mac) + Firefox | ✅ |
VoiceOver (Mac) + Safari | ✅ |
VoiceOver (iOS) + Safari | ✅ |
Jaws (PC) + Chrome | ✅ |
Jaws (PC) + Edge | ✅ |
Jaws (PC) + Firefox | ✅ |
NVDA (PC) + Chrome | ✅ |
NVDA (PC) + Edge | ✅ |
NVDA (PC) + Firefox | ✅ |
Narrator (PC) + Chrome | ✅ |
Narrator (PC) + Edge | ✅ |
Narrator (PC) + Firefox | ✅ |
TalkBack (Android) + Chrome | ✅ |
TalkBack (Android) + Firefox | ✅ |
TalkBack (Android) + Samsung Internet | ✅ |
Specifications
- DOM interface: HTMLElement
- ARIA Authoring Practices: Tabs