Tabs allow users to switch between different content panels. Each tab panel should have a unique ID for anchor linking.
data-tabs attributerole="tablist" with tab buttonsaria-labelledby attributes<div class="tabs" data-tabs>
<!-- Tab List (Buttons) -->
<div class="tabs__list" role="tablist">
<button
class="tabs__tab"
id="tab-1"
role="tab"
aria-selected="true"
aria-controls="panel-1"
tabindex="0">
Tab 1
</button>
<button
class="tabs__tab"
id="tab-2"
role="tab"
aria-selected="false"
aria-controls="panel-2"
tabindex="-1">
Tab 2
</button>
</div>
<!-- Tab Panels (Content) -->
<div class="tabs__panels">
<div
class="tabs__panel"
id="panel-1"
role="tabpanel"
aria-labelledby="tab-1"
aria-hidden="false">
Content for Tab 1
</div>
<div
class="tabs__panel"
id="panel-2"
role="tabpanel"
aria-labelledby="tab-2"
aria-hidden="true">
Content for Tab 2
</div>
</div>
</div>
<section class="my-section u-background-white u-padding-xl">
<div class="u-container">
<div class="tabs" data-tabs>
<div class="tabs__list" role="tablist">
<button
class="tabs__tab"
id="button-features"
role="tab"
aria-selected="true"
aria-controls="features"
tabindex="0">
Features
</button>
<button
class="tabs__tab"
id="button-pricing"
role="tab"
aria-selected="false"
aria-controls="pricing"
tabindex="-1">
Pricing
</button>
</div>
<div class="tabs__panels">
<div
class="tabs__panel"
id="features"
role="tabpanel"
aria-labelledby="button-features"
aria-hidden="false">
<h3>Features</h3>
<p>Content about features...</p>
</div>
<div
class="tabs__panel"
id="pricing"
role="tabpanel"
aria-labelledby="button-pricing"
aria-hidden="true">
<h3>Pricing</h3>
<p>Content about pricing...</p>
</div>
</div>
</div>
</div>
</section>
| Element | Attribute | Value | Notes |
|---|---|---|---|
| Container | data-tabs |
(none) | Required for JavaScript initialization |
| Tab Button | role="tab" |
(none) | ARIA role |
| Tab Button | id |
unique | e.g., "button-features" |
| Tab Button | aria-controls |
panel-id | Matches panel id |
| Tab Button | aria-selected |
"true" or "false" |
"true" for active tab |
| Tab Button | tabindex |
"0" or "-1" |
"0" for active, "-1" for inactive |
| Tab Panel | role="tabpanel" |
(none) | ARIA role |
| Tab Panel | id |
unique | Must match button’s aria-controls |
| Tab Panel | aria-labelledby |
button-id | Matches button’s id |
| Tab Panel | aria-hidden |
"true" or "false" |
"false" for active panel |
| Element | Attribute | Value | Notes |
|---|---|---|---|
| Container | data-tabs-autoplay |
(none) | Opt-in autoplay that cycles through tabs automatically |
| Container | data-tabs-autoplay-interval |
number (ms) | Optional. Defaults to 4000. Values under 1500 are ignored |
Autoplay is opt-in and only runs when there are 2+ tab panels.
Add data-tabs-autoplay to the tabs container:
<div class="tabs" data-tabs data-tabs-autoplay>
<!-- tablist + panels -->
</div>
Add data-tabs-autoplay-interval in milliseconds:
<div class="tabs" data-tabs data-tabs-autoplay data-tabs-autoplay-interval="6000">
<!-- tablist + panels -->
</div>
Notes:
4000ms1500ms (lower values are ignored and the default is used)"button-features" or "button-pricing""button-" prefix: "features" or "pricing"/#features)Tabs support URL anchors. When a user visits /#features, the corresponding tab will automatically be activated.
The JavaScript:
Example URLs:
/#features → Activates tab with aria-controls="features"/#pricing → Activates tab with aria-controls="pricing"See ui/website/components/home/packages.html for a full example:
You can have multiple tab sets on the same page. Each needs its own data-tabs container:
<!-- First tab set -->
<div data-tabs>
<!-- tabs -->
</div>
<!-- Second tab set -->
<div data-tabs>
<!-- tabs -->
</div>
data-tabs-autoplay is present, tabs cycle automatically until the user interacts (pointer/tap/click anywhere in the tabs instance, or keyboard focus), then autoplay stops.The tabs component comes with minimal built-in styling in ui/website/css/shared/tabs.css. This is intentional because tabs are used in different contexts with very different visual designs:
You’ll need to add custom CSS for your specific use case. The base styles provide:
Example: See ui/website/css/pages/home/packages.css and ui/website/css/pages/parents/tabs.css for how tabs are styled differently on each page.
ui/website/css/shared/tabs.cssui/website/js/components/tabs.jsui/website/components/home/packages.html