Bootstrap 5 Tab Content
Bootstrap 5 Tab Content is a navigation pattern that pairs a set of clickable tab triggers with corresponding content panels, showing one panel at a time. It uses the .nav-tabs or .nav-pills classes for the trigger list and .tab-content with .tab-pane divs for the panels. Use it when you need to present related but distinct information within a single page area without requiring a page reload.
Bootstrap class
.tab-contentCommon use cases
- A SaaS pricing page that separates Monthly and Annual billing options into two tabs, letting users toggle between plans without scrolling.
- A product detail page with tabs for Description, Specifications, Reviews, and Shipping Info, keeping all purchase-relevant content in one viewport area.
- A user account dashboard that organises Profile Settings, Security, Notifications, and Billing into tabs so users navigate directly to what they need.
- A developer documentation page that shows code examples in multiple languages (JavaScript, Python, PHP) via tabs, each tab displaying the equivalent snippet.
Variants and classes
| Variant | Description and classes |
|---|---|
| Panes | Container for the panels a nav switches between.tab-content + tab-pane |
| Fade | Panels fade in when shown.tab-pane fade + show active |
| Pill trigger | Pills instead of tabs drive the panes.nav-pills + data-bs-toggle="pill" |
| Vertical layout | Nav on the left, panes on the right.d-flex align-items-start + nav flex-column nav-pills |
Code example
<ul class="nav nav-tabs" id="productTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="description-tab" data-bs-toggle="tab" data-bs-target="#description" type="button" role="tab" aria-controls="description" aria-selected="true">Description</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="specs-tab" data-bs-toggle="tab" data-bs-target="#specs" type="button" role="tab" aria-controls="specs" aria-selected="false">Specifications</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="reviews-tab" data-bs-toggle="tab" data-bs-target="#reviews" type="button" role="tab" aria-controls="reviews" aria-selected="false">Reviews</button>
</li>
</ul>
<div class="tab-content" id="productTabsContent">
<div class="tab-pane fade show active p-3" id="description" role="tabpanel" aria-labelledby="description-tab">
<p>The Merino Wool Crew Neck is crafted from 100% ethically sourced New Zealand merino. Lightweight, breathable, and naturally odour-resistant, ideal for travel or everyday wear.</p>
</div>
<div class="tab-pane fade p-3" id="specs" role="tabpanel" aria-labelledby="specs-tab">
<ul class="mb-0">
<li>Material: 100% Merino Wool (18.5 micron)</li>
<li>Weight: 180gsm</li>
<li>Sizes: XS to 3XL</li>
<li>Machine washable at 30°C</li>
</ul>
</div>
<div class="tab-pane fade p-3" id="reviews" role="tabpanel" aria-labelledby="reviews-tab">
<p><strong>Sarah M.</strong> "Worn this on a two-week trip with no issues. Packs tiny and feels great against the skin."</p>
<p><strong>Tom R.</strong> "The sizing runs slightly slim. Order up if you're between sizes."</p>
</div>
</div>Live examples
Basic Tab Content
Canvas template variants
Canvas Builder builds pages on the Canvas HTML template, which adds its own styled versions of Bootstrap 5 components. Variants you can ask for in a prompt:
- Canvas Builder generated tab content with custom colours
- Tab Content with interactive states
- Responsive tab content for all screen sizes
Best practices
Always pair aria-controls and aria-labelledby correctly
Each tab button's aria-controls value must match the id of its corresponding .tab-pane, and each pane's aria-labelledby must match the button's id. Skipping this breaks keyboard navigation and screen reader announcements.
Use fade class for smooth panel transitions
Adding the fade class alongside tab-pane enables a CSS opacity transition between panels. The initially active pane also needs the show class, i.e. class="tab-pane fade show active", otherwise it renders invisible on load.
Switch to .nav-pills for card or sidebar layouts
Replace .nav-tabs with .nav-pills when your tabs sit inside a card, a sidebar, or against a coloured background. Pills have no bottom border dependency and adapt visually without extra CSS overrides.
Programmatically control tabs with the Bootstrap JS API
Use const tab = new bootstrap.Tab(document.querySelector('#specs-tab')); tab.show(); to activate a specific tab from JavaScript, useful when deep-linking via URL hash or responding to form validation errors in a specific panel.
FAQ
Can I link directly to a specific tab using a URL hash?
DOMContentLoaded, read window.location.hash, find the matching tab trigger element, and call bootstrap.Tab.getOrCreateInstance(triggerEl).show(). Also listen to the shown.bs.tab event to update the URL hash as users switch tabs, enabling shareable URLs.How do I customise the active tab indicator colour to match my brand?
.nav-tabs, the active state is controlled by --bs-nav-tabs-link-active-color and --bs-nav-tabs-link-active-border-color CSS custom properties. Override them on your .nav-tabs selector: .nav-tabs { --bs-nav-tabs-link-active-color: #2563eb; --bs-nav-tabs-link-active-border-color: #2563eb #2563eb #fff; }. For .nav-pills, override --bs-nav-pills-link-active-bg to change the pill background colour.How does Canvas Builder generate Tab Content components?
id / aria-controls / aria-labelledby relationships pre-wired and correct. It applies your project's brand colours to the active tab indicator via Bootstrap CSS custom property overrides scoped to the component, and outputs mobile-friendly markup where long tab lists collapse gracefully on small screens.