Tab
Tab components provide dynamic tabbed interfaces for organizing content into separate views that users can switch between.
Playground
Experiment with the Tab component by adjusting the props below:
Interactive Tab Playground
Controls
Preview
Home Content
This is the home tab content.
Code
<Tab.Root>
<Nav.Root itemStyle="tabs">
<Nav.Item>
<Tab.NavLink targetPaneId="#home" id="tab-home" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#profile" id="tab-profile" >Profile</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#contact" id="tab-contact" >Contact</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content>
<Tab.Pane id="home" isActive={true} doFade={true}>
<h5 class="mt-3">Home Content</h5>
<p>This is the home tab content.</p>
</Tab.Pane>
<Tab.Pane id="profile" doFade={true}>
<h5 class="mt-3">Profile Content</h5>
<p>This is the profile tab content.</p>
</Tab.Pane>
<Tab.Pane id="contact" doFade={true}>
<h5 class="mt-3">Contact Content</h5>
<p>This is the contact tab content.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
Basic Example
The Tab component combines Nav components with tab content panes for creating a tabbed interface. The active tab is
controlled by the isActive prop on both the Tab.NavLink and Tab.Pane components.
Home Content
This is the home content panel.
<Tab.Root>
<Nav.Root itemStyle="tabs">
<Nav.Item>
<Tab.NavLink targetPaneId="#home" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#profile">Profile</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#messages">Messages</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#settings" isDisabled={true}>Disabled</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content>
<Tab.Pane id="home" isActive={true}>
<h5 class="mt-3">Home Content</h5>
<p>This is the home content panel.</p>
</Tab.Pane>
<Tab.Pane id="profile">
<h5 class="mt-3">Profile Content</h5>
<p>This is the profile content panel.</p>
</Tab.Pane>
<Tab.Pane id="messages">
<h5 class="mt-3">Messages Content</h5>
<p>This is the messages content panel.</p>
</Tab.Pane>
<Tab.Pane id="settings">
<h5 class="mt-3">Settings Content</h5>
<p>This is the settings content panel.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
Fade Effect
Add the doFade prop to your tab panes to enable a fade transition effect when switching between tabs.
Home Content with Fade
This tab will fade in and out when switching.
<Tab.Root>
<Nav.Root itemStyle="tabs">
<Nav.Item>
<Tab.NavLink targetPaneId="#home-fade" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#profile-fade">Profile</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content>
<Tab.Pane id="home-fade" isActive={true} doFade={true}>
<h5 class="mt-3">Home Content with Fade</h5>
<p>This tab will fade in and out when switching.</p>
</Tab.Pane>
<Tab.Pane id="profile-fade" doFade={true}>
<h5 class="mt-3">Profile Content with Fade</h5>
<p>This tab will also fade in and out when switching.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
Pills
You can use pills instead of tabs by setting itemStyle="pills" on the Nav.Root component.
Home Pills Content
This is the pills-styled home tab content.
<Tab.Root>
<Nav.Root itemStyle="pills">
<Nav.Item>
<Tab.NavLink targetPaneId="#pills-home" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#pills-profile">Profile</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#pills-contact">Contact</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content>
<Tab.Pane id="pills-home" isActive={true}>
<h5 class="mt-3">Home Pills Content</h5>
<p>This is the pills-styled home tab content.</p>
</Tab.Pane>
<Tab.Pane id="pills-profile">
<h5 class="mt-3">Profile Pills Content</h5>
<p>This is the pills-styled profile tab content.</p>
</Tab.Pane>
<Tab.Pane id="pills-contact">
<h5 class="mt-3">Contact Pills Content</h5>
<p>This is the pills-styled contact tab content.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
Vertical Pills
Stack your navigation by using the verticalBreakpoint="xs" prop on the Nav.Root component.
Home Content
This is the content for the home tab in vertical pills layout.
<div class="d-flex align-items-start">
<Tab.Root>
<Nav.Root itemStyle="pills" verticalBreakpoint="xs" class="me-3">
<Nav.Item>
<Tab.NavLink targetPaneId="#v-pills-home" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#v-pills-profile">Profile</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#v-pills-messages">Messages</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#v-pills-settings">Settings</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content class="flex-grow-1">
<Tab.Pane id="v-pills-home" isActive={true}>
<h5 class="mt-0">Home Content</h5>
<p>This is the content for the home tab in vertical pills layout.</p>
</Tab.Pane>
<Tab.Pane id="v-pills-profile">
<h5 class="mt-0">Profile Content</h5>
<p>This is the content for the profile tab in vertical pills layout.</p>
</Tab.Pane>
<Tab.Pane id="v-pills-messages">
<h5 class="mt-0">Messages Content</h5>
<p>This is the content for the messages tab in vertical pills layout.</p>
</Tab.Pane>
<Tab.Pane id="v-pills-settings">
<h5 class="mt-0">Settings Content</h5>
<p>This is the content for the settings tab in vertical pills layout.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
</div>
Fill and Justify
To proportionately fill all available space with your nav items, use itemLayout="fill" or itemLayout="justified" on the Nav.Root component. The "fill" option gives all nav items equal width, while "justified" gives them equal width but only
when all horizontal space is occupied.
Fill Example
Fill Tab Home
This content appears with the nav items filling the available width.
<Tab.Root>
<Nav.Root itemStyle="pills" itemLayout="fill">
<Nav.Item>
<Tab.NavLink targetPaneId="#fill-home" isActive={true}>Home</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#fill-profile">Profile</Tab.NavLink>
</Nav.Item>
<Nav.Item>
<Tab.NavLink targetPaneId="#fill-contact">Contact</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content>
<Tab.Pane id="fill-home" isActive={true}>
<h5 class="mt-3">Fill Tab Home</h5>
<p>This content appears with the nav items filling the available width.</p>
</Tab.Pane>
<Tab.Pane id="fill-profile">
<h5 class="mt-3">Fill Tab Profile</h5>
<p>This content appears with the nav items filling the available width.</p>
</Tab.Pane>
<Tab.Pane id="fill-contact">
<h5 class="mt-3">Fill Tab Contact</h5>
<p>This content appears with the nav items filling the available width.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
Custom Classes
You can add custom CSS classes to each component in the Tab structure to further customize styling.
Home with Custom Classes
This is the content with custom CSS classes applied.
<Tab.Root>
<Nav.Root itemStyle="tabs" class="mb-3 nav-custom">
<Nav.Item class="custom-item">
<Tab.NavLink targetPaneId="#custom-home" isActive={true} class="rounded-top">Home</Tab.NavLink>
</Nav.Item>
<Nav.Item class="custom-item">
<Tab.NavLink targetPaneId="#custom-profile" class="rounded-top">Profile</Tab.NavLink>
</Nav.Item>
</Nav.Root>
<Tab.Content class="border p-3 custom-content">
<Tab.Pane id="custom-home" isActive={true} class="custom-pane">
<h5>Home with Custom Classes</h5>
<p>This is the content with custom CSS classes applied.</p>
</Tab.Pane>
<Tab.Pane id="custom-profile" class="custom-pane">
<h5>Profile with Custom Classes</h5>
<p>This is the content with custom CSS classes applied.</p>
</Tab.Pane>
</Tab.Content>
</Tab.Root>
API Reference
Tab.Root Props
| Name | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply to the component |
elementRef | HTMLElement | null | null | Reference to the DOM element |
id | string | Auto-generated | Unique identifier for the tab container |
Tab.Content Props
| Name | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply to the component |
elementRef | HTMLElement | null | null | Reference to the DOM element |
Tab.NavLink Props
| Name | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply to the component |
elementRef | HTMLElement | null | null | Reference to the DOM element |
id | string | Auto-generated | Unique identifier for the link |
isActive | boolean | false | Whether the link is active |
isDisabled | boolean | false | Whether the link is disabled |
role | 'button' | 'tab' | Auto-determined | ARIA role for the link. Defaults to 'tab' if within tablist context. |
targetPaneId | string | '#!' | The ID of the tab pane to link to. |
Tab.NavLink Props
| Name | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply to the component |
doFade | boolean | false | Whether to use fade transition when showing/hiding |
elementRef | HTMLElement | null | null | Reference to the DOM element |
id | string | Auto-generated | Unique identifier for the tab pane |
isActive | boolean | false | Whether the pane is initially visible |
onHide | function | noop | Callback when the pane is about to be hidden |
onHidden | function | noop | Callback when the pane has been hidden |
onShow | function | noop | Callback when the pane is about to be shown |
onShown | function | noop | Callback when the pane has been shown |
CSS Classes
The component applies Bootstrap's tab classes based on the provided props:
tab-content- Applied to Tab.Content componentstab-pane- Applied to Tab.Pane componentsactive- Applied to Tab.Pane when isActive=truefade- Applied to Tab.Pane when doFade=trueshow- Applied to Tab.Pane during transition when doFade=true
Accessibility
The Tab component automatically applies proper ARIA attributes:
role="tabpanel"- Applied to Tab.Pane componentsaria-labelledby- Links the Tab.Pane to its corresponding Tab.NavLinkaria-hidden- Set to "true" for inactive panes, "false" for active paneshidden- HTML attribute applied to inactive panes