Tabs
Use tabs to organize and navigate between different types of related content at the same level of hierarchy, in the same viewing area on a page.
Playground
Tab headers will not line-wrap if there is not enough space to display them all. Instead, the user will be able scroll them horizontally. A slight gradient will appear at the right edge to indicate there is hidden content.
Usage
Tabs consist of two main parts:
the "headers" (the clickable "tabs" themselves)
the "contents" (the content for each tab)
React Usage
Tabs
consists of TabsHeaders
and TabsContents
.
Inside of the TabsHeaders
, we have individual TabHeader
components, and inside of the TabsContents
we have individual TabContent
components.
Each TabHeader
matches up with a single TabContent
via the tabId
prop. Every TabHeader
and TabContent
must have a tabId
in order for Tabs
to be able to tell which TabContent
to show when a certain TabHeader
is clicked.
A defaultSelectedTabId
can be provided in order to specify the initially-selected tab. If you want to control the state beyond just the initial selection, check out the managing state section.
<Tabs defaultSelectedTabId="one"><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent></TabsContents></Tabs>
Vanilla Usage
In vanilla, Tabs headers are a series of radio buttons and labels.
The
tabs-headers
element that wraps the headers must haverole="tablist"
Each radio button needs a
value
property whose value is the selector of the contents element associated with that radio button. For instance, if the contents panel has an id ofexampleTab1
, then the input should havevalue="#exampleTab1"
Each radio button also must have
role="tab"
, and anaria-controls
property whose value is theid
of the tab panel that it goes with.The radio button associated with the default tab should have the property
checked="checked"
.You can disable a tab by putting the
disabled
property onto the radio button associated with that tab. The Tabs contents are a series of divs that are associated with those radio buttons.Each content panel must have
role="tabpanel"
and anaria-labelledby
attributes whose value is theid
of the<label>
in the tabs headers that the tab panel goes with.
<div class="tabs"><div class="tabs-headers" role="tablist"><inputname="exampleTabHeaders"id="exampleTabHeader1"type="radio"value="#exampleTab1"checked="checked"role="tab"aria-controls="exampleTab1"/><label for="exampleTabHeader1" id="exampleTabHeader1Label">Header 1</label><inputname="exampleTabHeaders"id="exampleTabHeader2"type="radio"value="#exampleTab2"role="tab"aria-controls="exampleTab2"/><label for="exampleTabHeader2" id="exampleTabHeader2Label">Header 2</label></div><div class="tabs-contents"><divid="exampleTab1"class="tab-selected"role="tabpanel"aria-labelledby="exampleTabHeader1Label">Content 1</div><divid="exampleTab2"role="tabpanel"aria-labelledby="exampleTabHeader2Label">> Content 2</div></div></div>
Fixed-Width Headers
With this option, the tab headers all have a fixed minimum width (currently, about 240px), regardless of the width of their content. Use this to toggle between high-priority content.
Centered Headers
Use this option if you want the headers to be centered instead of left-aligned.
<Tabs centerHeaders defaultSelectedTabId="two"><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent></TabsContents></Tabs>
<div class="tabs tabs-center-headers"></div>
Dividing Line
You can hide the dividing line between the tabs headers and the tabs content.
<Tabs showDividingLine={false} defaultSelectedTabId="one"><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent></TabsContents></Tabs>
<div class="tabs tabs-no-dividing-line">etc.</div>
Sticky Headers
This option makes the headers sticky to the top of the screen if the tabs content is tall. This option will also automatically hide the dividing line between the tab headers and the tab content.
// this option is not yet available in React
<div class="tabs tabs-sticky-headers"></div>
Wrap Headers
This option makes the headers wrap to the next line if there isn't enough room.
<Tabs defaultSelectedTabId="one" wrapHeaders><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader><TabHeader tabId="three">Header 3 is much longer</TabHeader><TabHeader tabId="four">Header 4</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent><TabContent tabId="three">Content 3</TabContent><TabContent tabId="four">Content 4</TabContent></TabsContents></Tabs>
<div class="tabs tabs-wrap-headers">etc.</div>
"Mega" tabs
Using the "mega" size variant for the Tabs makes the tab headers huge.
Because of their large size, it is not recommended that you use more than 2 or 3 tabs in a "mega" Tabs set, and that you keep the text on the headers short. Otherwise, there won't be enough room on smaller screens.
<Tabs sizeVariant="mega" defaultSelectedTabId="three"><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader><TabHeader tabId="three">Header 3</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent><TabContent tabId="three">Content 3</TabContent></TabsContents></Tabs>
<div class="tabs tabs-mega">etc.</div>
Managing State in React
Most often with Tabs
it is not necessary for you to take ownership of the state (the currently-selected tab). The defaultSelectedTabId
prop is available if you'd like to specify which tab should be selected initially without committing to fully managing the Tabs
's state.
If you do want to control the state of the Tabs
yourself (e.g. other parts of your app care about which tab is currently selected), you can provide the selectedTabId
and onRequestTabChange
props.
onRequestTabChange
is invoked with the requested tabId and it is also passed a second arg which is the event
that triggered the change in case you need it.
() => {const [selectedTabId, setSelectedTabId] = React.useState('two')return (<TabsselectedTabId={selectedTabId}onRequestTabChange={requestedTabId => setSelectedTabId(requestedTabId)}><TabsHeaders><TabHeader tabId="one">Header 1</TabHeader><TabHeader tabId="two">Header 2</TabHeader></TabsHeaders><TabsContents><TabContent tabId="one">Content 1</TabContent><TabContent tabId="two">Content 2</TabContent></TabsContents></Tabs>)}
Components
Tabs
Prop | Type | Default | Description |
---|---|---|---|
fixedWidthHeaders | boolean | false | Whether or not the tabs have a shared fixed with |
fullWidthHeader | boolean | false | Whether the header spans the full width of its container |
centerHeaders | boolean | false | Whether or not the headers are centered |
stickyHeaders | boolean | false | Whether or not the headers are sticky |
wrapHeaders | boolean | false | Whether or not the headers will wrap |
showDividingLine | boolean | true | Whether or not there is a dividing line between headers and contents |
sizeVariant | "standard" | "mega" | standard | The size of the Tabs |
defaultSelectedTabId | string | The id of the tab which should be selected initially | |
selectedTabId | string | The id of the tab which should be selected | |
onRequestTabChange | (tabId: string, event: ChangeEvent<HTMLInputElement>) => void | Callback which is fired when the user requests a tab-change |
All other props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
TabsHeaders
TabsHeaders
has no props of its own
All props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
TabHeader
Prop | Type | Default | Description |
---|---|---|---|
tabId | string | required |
All other props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
TabsContents
TabsContents
has no props of its own
All props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
TabContent
Prop | Type | Default | Description |
---|---|---|---|
tabId | string | required |
All other props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
Guidelines
Don't
Nest one set of tabs inside another.
Use more than one row of tabs.
SEO Considerations
Content within any tab that's not the default tab is readable by Googlebot, but not SEO-friendly. Googlebot considers content you put behind these tabs as less important for users and for organic visibility (ranking). All major content must appear on the default tab; other tabs must contain less important information, since they will be deprecated by Googlebot in terms of ranking.
Whenever possible, instead of displaying the content behind a tab, use anchor links that point to a different location within the same page.