Skip to content

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>

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.