<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5HGSQD2L" height="0" width="0" style="display:none;visibility:hidden" title="GTM"></iframe>

Tabs

Navigate between different types of related content at the same level of hierarchy.
styleKeys: tabsscriptKeys: tabs
Warning:

⚠️ Some props/prop values deprecated in SWAN v3.3
Refer to the information on props/prop values provided further down this page. Find more information and migration documentation in the Deprecation roadmap.

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.

Usage

The preview has been updated.

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.

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.

Share

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.

Share

Centered Headers

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

The preview has been updated.

Dividing Line

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

The preview has been updated.

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.

The preview has been updated.

Wrap Headers

Warning:

⚠️ wrapHeaders is deprecated in SWAN v3.3 No direct replacement for better semantic roles on SWAN components. Use the default behaviour.

This option makes the headers wrap to the next line if there isn't enough room.

The preview has been updated.

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.

The preview has been updated.

Best practices

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 on the same page.

Props

Tabs
This component is implemented using the <div /> as the root element. You can utilize the native attributes supported by <div /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
proptyperequireddescriptiondefault
centerHeadersboolean | nullfalse
Whether or not the headers are centered horizontally in their container
null
stickyHeadersboolean | nullfalse
Whether or not the headers are sticky. Also hides the dividing line between the tab headers and content
null
wrapHeadersboolean | nullfalse
⚠️ Deprecated - This is deprecated without a replacement. Tabs will be scrollable.
Whether or not the headers will wrap
null
showDividingLineboolean | nullfalse
Whether or not there is a dividing line between headers and contents
true
defaultSelectedTabIdstring | nullfalse
The id of the tab which should be selected initially, used for uncontrolled tabs
null
selectedTabIdstring | nullfalse
The id of the tab which should be selected. Used when controlling the state of the tabs
null
onRequestTabChange((tabId: string | null, event: ChangeEvent<HTMLInputElement>) => void) | nullfalse
Callback which is fired when the user requests a tab-change
null
TabHeader
This component is implemented using the <input /> as the root element. You can utilize the native attributes supported by <input /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
proptyperequireddescriptiondefault
tabIdstringtrue
The id of the matching tab
null
disabledboolean | nullfalse
Whether or not the header is disabled
null
inputPropsOmit<TabHeaderInputProps, "ref" | "tabId"> | nullfalse
Props passed to the TabHeaderInput
null
TabsHeaders
This component is implemented using the <div /> as the root element. You can utilize the native attributes supported by <div /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
TabHeaderLabel
This component is implemented using the <label /> as the root element. You can utilize the native attributes supported by <label /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
proptyperequireddescriptiondefault
tabIdstringtrue
The id of the matching tab
null
TabHeaderInput
This component is implemented using the <input /> as the root element. You can utilize the native attributes supported by <input /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
proptyperequireddescriptiondefault
tabIdstringtrue
The id of the matching tab
null
TabContent
This component is implemented using the <div /> as the root element. You can utilize the native attributes supported by <div /> tag. The ref is directly assigned to the root element, allowing you to access and manipulate it as needed.
See core props for additional props that can be applied to this component.
proptyperequireddescriptiondefault
tabIdstringtrue
-
null
Was this page useful?

Thanks for your feedback!

Feel free to include your name if you wish to have a follow up conversation.


Published: Jan 7, 2022Last updated: Sep 3, 2024