If you want the user to be able to switch between different content options, the tab is your component!

Overview

The tabs tend to be used to get some part of the content displaying different subjects. It's a nice and clear way to display content in a condensed but intuitive way.

A tab will take the whole width of its parent container.

Les trois petits cochons et leurs maisons

Il était évident qu'une maison construite en paille ne tiendrait pas la route. Il s'agit pourtant d'un matériau écologique, facile à maîtriser et possédant d'excellentes propriétés isolantes. Hélas! Le grand méchant loup...

My three favourite beers

Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.

Other beers

A light and refreshing hallmark of the beer family, pilsners are identified by their crisp body, lightness of color and superb drinkability on hot summer days. Examples include Becks, Prima Pils, Harpoon Pilsner, Bitburger, St. Pauli Girl, and Spaten Pils.

Usage

Dependencies

To get the tabs component working, include the dependencies in your project in the following order:

  1. npm
  2. Sass
  3. JS
"design-system": "git+ssh://git@github.com/Selectra-Dev/design-system.git"
@import 'design-system/src/scss/02-molecules/tabs';
import initButtonGroups from 'design-system/src/js/02-molecules/tabs';

Basic code

Tabs are structured in the following way:

  • div class="tabs" general container which contains:
    • div class="tablist" a group in which you include as many tabs as you want
      • button class="tablist__tab" Label 1
      • button class="tablist__tab" Label 2
      • button class="tablist__tab" Label 3
    • div class="tabpanel" Tabpanel 1
      • div class="tabpanel__body" wrapper for the content.
    • div class="tabpanel" Tabpanel 2
      • div class="tabpanel__body" wrapper for the content.
    • div class="tabpanel" Tabpanel 3
      • div class="tabpanel__body" wrapper for the content.

  1. Html
  2. Pug
  3. JS
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#favourite-beers">
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" role="tab" aria-selected="true" aria-controls="ale-tab" id="ale" tabindex="-1">Ale </button>
    <button class="tablist__tab tablist__tab--md" role="tab" aria-selected="false" aria-controls="lager-tab" id="lager" tabindex="-1">Lager </button>
    <button class="tablist__tab tablist__tab--md" role="tab" aria-selected="false" aria-controls="malt-tab" id="malt" tabindex="-1">Malt </button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale" tabindex="0">
    <div class="tabpanel__body">
      <p>Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</p>
    </div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager" tabindex="0" hidden="hidden">
    <div class="tabpanel__body">
      <p>Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

</div> </div> <div class="tabpanel" role="tabpanel" id="malt-tab" aria-labelledby="malt" tabindex="0" hidden="hidden"> <div class="tabpanel__body"> <p>Sweet tooth? Malts, often containing notes of caramel, toffee, and nuts, are dark and sweet in flavour.</p> </div> </div> </div>
.tabs
  .tablist(role="tablist", aria-labelledby="#tabid1", data-switching="auto")
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(role="tab", aria-selected="true", aria-controls="-tab", id="ale", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md(role="tab", aria-selected="false", aria-controls="lager-tab", id="lager", tabindex="-1") Lager
    button.tablist__tab.tablist__tab--md(role="tab", aria-selected="false", aria-controls="malt-tab", id="malt", tabindex="-1", data-deletable="") Malt
  .tabpanel(role="tabpanel", id="ale-tab", aria-labelledby="ale", tabindex="0")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(role="tabpanel", id="lager-tab", aria-labelledby="lager", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.
  .tabpanel(role="tabpanel", id="malt-tab", aria-labelledby="malt", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Sweet tooth? Malts, often containing notes of caramel, toffee, and nuts, are dark and sweet in flavour.
Tabs();

🧐A11y wise: Ensure to use the correct role attributes: tab and tabpanel must be contained inside a parent element with the role="tablist" attribute.

In addition to that, the aria-controls of a tablist should be the same as the id of its relative tab.

For more information checkout the HTML attributes at the end of this page.

Modifiers

Add the following modifier to change the appearance of tabs.

Size

Size modifier comes in 3 variants: small, medium and large. It allows you to change the font size and the padding of the tablist items making them smaller or bigger.

Small (sm)

Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.


Medium (md)

Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.


Large (lg)

Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.

  1. HTML
  2. Pug
<!-- Small modifier -->
<button class="tablist__tab tablist__tab--sm" role="tab">Ale</button>

<!-- Medium modifier -->
<button class="tablist__tab tablist__tab--md" role="tab">Ale</button>

<!-- Large modifier -->
<button class="tablist__tab tablist__tab--lg" role="tab">Ale</button>
//- Small modifier
button.tablist__tab.tablist__tab--sm Ale

//- Medium modifier
button.tablist__tab.tablist__tab--md Ale

//- Large modifier
button.tablist__tab.tablist__tab--lg Ale

Selected

Selected modifier is intended for selecting a tab by default. If not applied, tab won't be selected ¯\_(ツ)_/¯.

The second tablist is selected here:

Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

No tablist selected here: (also changed the relevant attributes)

🧐 The selected tablist must have the aria-selected="true" boolean attribute, while the non-selected tablists must have the aria-selected="false".

The selected tab itself doesn't need any specific attribute for selection whereas the non-selected ones must have the hidden="hidden" attribute.


  1. HTML
  2. Pug
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#tabid1">
    <button class="tablist__tab tablist__tab--md" role="tab" aria-selected="false" aria-controls="lager-tab" id="lager">Lager</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" role="tab" aria-selected="true" aria-controls="lager-tab" id="lager">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager" tabindex="0">
    <div class="tabpanel__body">Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
.tabs
  .tablist(role="tablist", aria-labelledby="#tabid1")
    button.tablist__tab(role="tab", aria-selected="false", aria-controls="ale-tab", id="ale", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(role="tab", aria-selected="true", aria-controls="lager-tab", id="lager", tabindex="-1") Lager
  .tabpanel(role="tabpanel", id="ale-tab", aria-labelledby="ale", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(role="tabpanel", id="lager-tab", aria-labelledby="lager", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

HTML attributes

Attributes are important for the a11y.

Role

The role attribute is intended to clarify screen-reader users on which element is a tab of the tablist, and which element is a tabpanel. Here we must use three options:

  • "tablist"
  • "tab"
  • "tabpanel"
  1. HTML
  2. Pug
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#tabid1">
    <button class="tablist__tab tablist__tab--md" role="tab" aria-selected="false" aria-controls="ale-tab" id="ale" tabindex="-1">Ale</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" role="tab" aria-selected="true" aria-controls="lager-tab" id="lager" tabindex="-1">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale" tabindex="0">
    <div class="tabpanel__body">Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
.tabs
  .tablist(role="tablist", aria-labelledby="#tabid1")
    button.tablist__tab(role="tab", aria-selected="false", aria-controls="ale-tab", id="ale", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(role="tab", aria-selected="true", aria-controls="lager-tab", id="lager", tabindex="-1") Lager
  .tabpanel(role="tabpanel", id="ale-tab", aria-labelledby="ale", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(role="tabpanel", id="lager-tab", aria-labelledby="lager", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

Aria-labelledby

The aria-labelledby attribute establishes relationships between objects and their label. Its value should be one or more element ID. Here it must relate the tabpanel to its tab (button). It's also useful to use it to point the whole tablist to its label if there is one, as you can see for the first example.

  1. HTML
  2. Pug
<h4 id="two-favourite-beers">Two of my favourite beers<h4>
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#two-favourite-beers">
    <button class="tablist__tab tablist__tab--md" id="ale-id" role="tab" aria-selected="false" aria-controls="ale-tab" tabindex="-1">Lager</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" id="lager-id" role="tab" aria-selected="true" aria-controls="lager-tab" tabindex="-1">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale-id" tabindex="0">
    <div class="tabpanel__body">Ale are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager-id" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
h4#two-favourite-beers Two of my favourite beers
.tabs
  .tablist(role="tablist", aria-labelledby="#two-favourite-beers")
    button.tablist__tab(id="ale-id", role="tab", aria-selected="false", aria-controls="ale-tab", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(id="lager", role="tab", aria-selected="true", aria-controls="lager-tab", tabindex="-1") Lager
  .tabpanel(aria-labelledby="ale", role="tabpanel", id="ale-tab", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(aria-labelledby="lager", role="tabpanel", id="lager-tab", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

Aria-controls

The aria-controls attribute denotes which tabpanel a tab has control over.

The content of the tab's aria-controls attribute must match the tabpanel's id.

  1. HTML
  2. Pug
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#two-favourite-beers">
    <button class="tablist__tab tablist__tab--md" id="ale-id" role="tab" aria-controls="ale-tab" aria-selected="false" tabindex="-1">Lager</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" id="lager-id" role="tab" aria-controls="lager-tab" aria-selected="true" tabindex="-1">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale-id" tabindex="0">
    <div class="tabpanel__body">Ale are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager-id" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
.tabs
  .tablist(role="tablist", aria-labelledby="#two-favourite-beers")
    button.tablist__tab(id="ale-id", role="tab", aria-selected="false", aria-controls="ale-tab", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(id="lager", role="tab", aria-selected="true", aria-controls="lager-tab", tabindex="-1") Lager
  .tabpanel(aria-labelledby="ale", role="tabpanel", id="ale-tab", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(aria-labelledby="lager", role="tabpanel", id="lager-tab", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

Aria-selected

The aria-selected attribute establishes which tab is selected by default and which one is not. It's applied only to the tab element.

As it is a boolean attribute, so values can be aria-selected="false" or aria-selected="true"

Please note that in our Design System we also assign a CSS modifier class (tablist__tab--selected) to the tab that will be selected by default.

  1. HTML
  2. Pug
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#two-favourite-beers">
    <button class="tablist__tab tablist__tab--md" aria-selected="false" id="ale-id" role="tab" aria-controls="ale-tab" tabindex="-1">Lager</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" aria-selected="true" id="lager-id" role="tab" aria-controls="lager-tab" tabindex="-1">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale-id" tabindex="0">
    <div class="tabpanel__body">Ale are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager-id" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
.tabs
  .tablist(role="tablist", aria-labelledby="#two-favourite-beers")
    button.tablist__tab(aria-selected="false", id="ale-id", role="tab", aria-controls="ale-tab", tabindex="-1") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(aria-selected="true", id="lager", role="tab", aria-controls="lager-tab", tabindex="-1") Lager
  .tabpanel(aria-labelledby="ale", role="tabpanel", id="ale-tab", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(aria-labelledby="lager", role="tabpanel", id="lager-tab", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

Tabindex

The tabindex attribute is here to prevent the tabs to be focusable (as they are buttons so they are focusable by default), and to make the tabpanels focusable (as they are divs and aren't focusable by default).

We assign the value tabindex="-1" to the tab that won't be focusable, and the value tabindex="0" to the tabpanel that will be focusable.

  1. HTML
  2. Pug
<div class="tabs">
  <div class="tablist" role="tablist" aria-labelledby="#two-favourite-beers">
    <button class="tablist__tab tablist__tab--md" tabindex="-1" aria-selected="false" id="ale-id" role="tab" aria-controls="ale-tab">Lager</button>
    <button class="tablist__tab tablist__tab--md tablist__tab--selected" tabindex="-1" aria-selected="true" id="lager-id" role="tab" aria-controls="lager-tab">Lager</button>
  </div>
  <div class="tabpanel" role="tabpanel" id="ale-tab" aria-labelledby="ale-id" tabindex="0">
    <div class="tabpanel__body">Ale are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.</div>
  </div>
  <div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager-id" tabindex="0">
    <div class="tabpanel__body">Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.</div>
  </div>
</div>
.tabs
  .tablist(role="tablist", aria-labelledby="#two-favourite-beers")
    button.tablist__tab(tabindex="-1", aria-selected="false", id="ale-id", role="tab", aria-controls="ale-tab") Ale
    button.tablist__tab.tablist__tab--md.tablist__tab--selected(tabindex="-1", aria-selected="true", id="lager", role="tab", aria-controls="lager-tab") Lager
  .tabpanel(aria-labelledby="ale", role="tabpanel", id="ale-tab", tabindex="0", hidden="hidden")
    .tabpanel__body
      p Ales are full-bodied with hints of fruit or spice. They're also known to quench a mean thirst.
  .tabpanel(aria-labelledby="lager", role="tabpanel", id="lager-tab", tabindex="0")
    .tabpanel__body
      p Lager, the beer style almost everyone's familiar with, is known for its crispness and refreshing finish.

Hidden

The hidden attribute is applied only to the hidden tabpanels of our tablist. It's intended to be used like this hidden="hidden".


  1. HTML
  2. Pug
<div class="tablist" role="tablist" aria-labelledby="#favourite-beers">
  <button class="tablist__tab tablist__tab--md" role="tab" aria-selected="false" aria-controls="lager-tab" id="lager" tabindex="-1">Lager</button>
</div>
<div class="tabpanel" role="tabpanel" id="lager-tab" aria-labelledby="lager" tabindex="0">
.tablist(role="tablist", aria-labelledby="#tabid1")
  button.tablist__tab(role="tab", aria-selected="false", aria-controls="ale-tab", id="ale") Ale
.tabpanel(role="tabpanel", id="ale-tab", aria-labelledby="ale", tabindex="0", hidden="hidden")