Skip to content

Tabs

Tabs are UI elements for organizing and navigating between groups of related content.

Introduction

Tabs are implemented using a collection of related components:

  • <Tab /> - the tab element itself. Clicking on a tab displays its corresponding panel.
  • <TabsList /> - the container that houses the tabs. Responsible for handling focus and keyboard navigation between tabs.
  • <TabPanel /> - the card that hosts the content associated with a tab.
  • <Tabs /> - the top-level component that wraps the Tabs List and Tab Panel components so that tabs and their panels can communicate with one another.
My account page

Components

Usage

After installation, you can start building with this component collection using the following basic elements:

<span class="token keyword">import</span> Tab <span class="token keyword">from</span> <span class="token string">'@mui/base/Tab'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> TabsList <span class="token keyword">from</span> <span class="token string">'@mui/base/TabsList'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> TabPanel <span class="token keyword">from</span> <span class="token string">'@mui/base/TabPanel'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Tabs <span class="token keyword">from</span> <span class="token string">'@mui/base/Tabs'</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">MyApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tabs</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabsList</span></span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* tab one */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* tab two */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabsList</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* panel one */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* panel two */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tabs</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Basics

By default, Tab components and their corresponding panels are zero-indexed (i.e. the first tab has a value of 0, then 1, 2, etc.). Clicking on a given Tab opens the panel with the same value, which corresponds to the order in which each component is nested within its container.

Though not required, you can add the value prop to the Tab and Tab Panel to take control over how these components are associated with one another.

The following demo omits the value prop from the Tab components, and also defines 0 as the defaultValue for the Tabs component, which sets the first Tab and Panel as the defaults:

First page
Press Enter to start editing

The next demo shows how to apply custom styles to a set of tabs:

First page
Press Enter to start editing

Anatomy

The Tab components are each composed of a root slot with no interior slots:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Tabs-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>TabsList-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Tab-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>First tab<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Tab-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Second tab<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Tab-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Third tab<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>TabPanel-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>First panel<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>TabPanel-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Second panel<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>TabPanel-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Third panel<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>

Custom structure

Use the slots prop to override the root or any other interior slot:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span> <span class="token attr-name">slots</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token string">'span'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>

If you provide a non-interactive element such as a <span>, the Tab components will automatically add the necessary accessibility attributes.

Customization

Vertical

Tab components can be arranged vertically as well as horizontally.

When vertical, you must set orientation="vertical" on the <Tabs /> component so the user can navigate with the up and down arrow keys (rather than the default left-to-right behavior for horizontal tabs).

First page
Press Enter to start editing

Usage with TypeScript

In TypeScript, you can specify the custom component type used in the slots.root as a generic parameter of the unstyled component. This way, you can safely provide the custom root's props directly on the component:

<span class="token operator">&lt;</span>Tab<span class="token operator">&lt;</span><span class="token keyword">typeof</span> CustomComponent<span class="token operator">></span> slots<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> root<span class="token operator">:</span> CustomComponent <span class="token punctuation">}</span><span class="token punctuation">}</span> customProp <span class="token operator">/</span><span class="token operator">></span>

The same applies for props specific to custom primitive elements:

<span class="token operator">&lt;</span>Tab<span class="token operator">&lt;</span><span class="token string">'button'</span><span class="token operator">></span> slots<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> root<span class="token operator">:</span> <span class="token string">'button'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span>

Third-party routing library

A common use case for tabs is to implement client-side navigation that doesn't require an HTTP round-trip to the server.

The Tab component provides the slots prop to handle this, as shown below:

Current route: /drafts

Press Enter to start editing

Accessibility

(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/tabs/)

The following steps are necessary to make the Tab component suite accessible to assistive technology:

  1. Label <Tabs /> with aria-label or aria-labelledby.
  2. Connect each <Tab /> to its corresponding <TabPanel /> by setting the correct id, aria-controls and aria-labelledby.

The demos below illustrate the proper use of ARIA labels.

Keyboard navigation

By default, when using keyboard navigation, the Tab components open via manual activation—that is, the next panel is displayed only after the user activates the tab with either Space, Enter, or a mouse click.

This is the preferable behavior for tabs in most cases, according to the WAI-ARIA authoring practices.

Alternatively, you can set the panels to be displayed automatically when their corresponding tabs are in focus—this behavior of the selection following the focus is known as automatic activation.

To enable automatic activation, pass the selectionFollowsFocus prop to the <Tabs /> component:

<span class="token comment">/* Tabs where selection follows focus */</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tabs</span></span> <span class="token attr-name">selectionFollowsFocus</span> <span class="token punctuation">/></span></span>

The following demo pair illustrates the difference between manual and automatic activation. Move the focus to a tab in either demo and navigate with the arrow keys to observe the difference:

Selection following focus:

Selection independent of focus (default behavior):