Vistaprint
scriptKeystabsstyleKeystabs

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.

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.

jsx
<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 have role="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 of exampleTab1, then the input should have value="#exampleTab1"

  • Each radio button also must have role="tab", and an aria-controls property whose value is the id 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 an aria-labelledby attributes whose value is the id of the <label> in the tabs headers that the tab panel goes with.

markup
<div class="tabs">
<div class="tabs-headers" role="tablist">
<input
name="exampleTabHeaders"
id="exampleTabHeader1"
type="radio"
value="#exampleTab1"
checked="checked"
role="tab"
aria-controls="exampleTab1"
/>
<label for="exampleTabHeader1" id="exampleTabHeader1Label">Header 1</label>
<input
name="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">
<div
id="exampleTab1"
class="tab-selected"
role="tabpanel"
aria-labelledby="exampleTabHeader1Label"
>
Content 1
</div>
<div
id="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.

Content 1
Content 2
Share
Share
jsx
<div class="tabs tabs-fixed-width-headers"></div>

Centered Headers

Use this option if you want the headers to be centered instead of left-aligned.

Content 1
Content 2
Share
Share
jsx
<div class="tabs tabs-center-headers"></div>

Dividing Line

You can hide the dividing line between the tabs headers and the tabs content.

Content 1
Content 2
Share
Share
jsx
<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.

Content 1
Content 2
Content 3
Content 4
jsx
// 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.

Content 1
Content 2
Content 3
Content 4
Share
Share
jsx
<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.

Content 1
Content 2
Content 3
Share
Share
jsx
<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.

Content 1
Content 2
Share
Share
jsx

Components

Tabs

PropTypeDefaultDescription
fixedWidthHeadersbooleanfalse

Whether or not the tabs have a shared fixed with

fullWidthHeaderbooleanfalse

Whether the header spans the full width of its container

centerHeadersbooleanfalse

Whether or not the headers are centered

stickyHeadersbooleanfalse

Whether or not the headers are sticky

wrapHeadersbooleanfalse

Whether or not the headers will wrap

showDividingLinebooleantrue

Whether or not there is a dividing line between headers and contents

sizeVariant"standard" | "mega"standard

The size of the Tabs

defaultSelectedTabIdstring

The id of the tab which should be selected initially

selectedTabIdstring

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 thecomponentprop(default: <div/>)

TabsHeaders

TabsHeaders has no props of its own

All props are forwarded to the element specified in thecomponentprop(default: <div/>)

TabHeader

PropTypeDefaultDescription
tabIdstringrequired

All other props are forwarded to the element specified in thecomponentprop(default: <div/>)

TabsContents

TabsContents has no props of its own

All props are forwarded to the element specified in thecomponentprop(default: <div/>)

TabContent

PropTypeDefaultDescription
tabIdstringrequired

All other props are forwarded to the element specified in thecomponentprop(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.