Bootstrap Tabs and Pills
Tabs and pills let users switch between related content panels without navigating to a new page. This lesson covers building both styles and wiring them to content panes.
Bootstrap Tabs and Pills Overview
Both tabs and pills share the same underlying structure: a .nav element containing .nav-item and .nav-link entries, paired with a .tab-content container holding .tab-pane elements. The visual difference is purely styling—nav-tabs renders bordered tab-style triggers, while nav-pills renders rounded, pill-shaped buttons.
Each nav-link uses data-bs-toggle="tab" (or "pill") along with data-bs-target pointing to its matching tab-pane id, and Bootstrap's JavaScript swaps the active pane, handles fade transitions, and manages ARIA attributes for accessible tab navigation.
| Concept | Description | Common Usage |
| nav-tabs | Bordered, tab-styled navigation | Classic tabbed interfaces |
| nav-pills | Rounded, button-styled navigation | Softer, modern tab-like navigation |
| .tab-content / .tab-pane | Container and individual content panels | Panels shown/hidden based on active tab |
| data-bs-toggle="tab"/"pill" | Marks a nav-link as a tab trigger | Switching the active pane on click |
| nav-fill / nav-justified | Distributes nav items evenly across width | Full-width, evenly spaced tab bars |
Bootstrap Tabs and Pills Example
<ul class="nav nav-tabs" id="profileTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#about" type="button" role="tab" aria-controls="about" aria-selected="true">About</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="false">Settings</button>
</li>
</ul>
<div class="tab-content mt-3">
<div class="tab-pane fade show active" id="about" role="tabpanel">Profile information goes here.</div>
<div class="tab-pane fade" id="settings" role="tabpanel">Account settings go here.</div>
</div>
Each nav-link uses data-bs-toggle="tab" with a data-bs-target matching a tab-pane's id, and role/aria attributes describe the relationship between tabs and panels for screen readers. The active pane combines show and active classes together with the fade transition class for a smooth switch between panels.
Top 10 Bootstrap Tabs and Pills Examples
These are the tab and pill patterns you'll use to build switchable content interfaces.
| # | Example | Syntax |
| 1 | Tabs nav | <ul class="nav nav-tabs">...</ul> |
| 2 | Pills nav | <ul class="nav nav-pills">...</ul> |
| 3 | Tab trigger link | <button class="nav-link" data-bs-toggle="tab" data-bs-target="#pane1">Tab 1</button> |
| 4 | Active tab trigger | <button class="nav-link active" data-bs-toggle="tab">Tab 1</button> |
| 5 | Tab content wrapper | <div class="tab-content">...</div> |
| 6 | Individual tab pane | <div class="tab-pane fade show active" id="pane1">Content</div> |
| 7 | Vertical tabs layout | <div class="d-flex"><div class="nav flex-column nav-pills">...</div></div> |
| 8 | Justified full-width tabs | <ul class="nav nav-tabs nav-justified">...</ul> |
| 9 | Fill evenly-spaced tabs | <ul class="nav nav-pills nav-fill">...</ul> |
| 10 | Disabled tab | <button class="nav-link disabled" data-bs-toggle="tab">Locked</button> |
Popular Real-World Bootstrap Tabs and Pills Examples
These tab and pill patterns commonly organize profiles, dashboards, and product detail pages.
| Scenario | Pattern |
| Profile page tabs (About / Posts / Settings) | <ul class="nav nav-tabs">...</ul> |
| Product detail tabs (Description / Reviews / Shipping) | <ul class="nav nav-tabs">...</ul> |
| Dashboard filter pills | <ul class="nav nav-pills">...</ul> |
| Vertical settings navigation | <div class="nav flex-column nav-pills">...</div> |
| Pricing period toggle (Monthly / Yearly) | <ul class="nav nav-pills justify-content-center">...</ul> |
| Code example language switcher | <ul class="nav nav-tabs"><li class="nav-item"><button class="nav-link">JavaScript</button></li></ul> |
| Justified full-width mobile tabs | <ul class="nav nav-tabs nav-justified">...</ul> |
| Onboarding step tabs | <ul class="nav nav-pills nav-fill">...</ul> |
Best Practices
- Use nav-tabs for traditional document-style sections and nav-pills for a softer, app-like feel.
- Always include role="tablist", role="tab", and role="tabpanel" for accessible tab semantics.
- Keep aria-selected in sync with the currently active tab.
- Use nav-fill or nav-justified when the tab bar should span the full container width evenly.
- Wrap related tab triggers and panes with matching, descriptive ids instead of generic numbers.
- Use vertical pills for settings-style navigation with many sections.
- Avoid placing more tabs than comfortably fit in one row on mobile; consider a dropdown or scroll instead.
Common Mistakes
- Mismatching data-bs-target and the tab-pane's id, so clicking a tab does nothing.
- Forgetting the active class on both the initial nav-link and its matching tab-pane.
- Omitting ARIA roles and attributes, making tabs hard to use with screen readers.
- Using disabled without also setting aria-disabled and preventing default click behavior via CSS.
- Cramming too many tabs into a narrow container, causing overflow or wrapping issues.
- Mixing tabs and pills styling inconsistently across similar sections of the same app.
Key Takeaways
- Tabs and pills share the same markup structure; only the visual style differs.
- nav-link elements use data-bs-toggle="tab" paired with data-bs-target to control tab-pane visibility.
- tab-content and tab-pane hold the actual content shown for each tab.
- ARIA roles and attributes are essential for accessible tab navigation.
- nav-fill, nav-justified, and vertical layouts adapt tabs to different UI needs.
Pro Tip
For settings-style pages with many sections, use vertical nav-pills alongside the content area in a flex layout instead of horizontal tabs, giving users a persistent, scannable list of sections.