Tabs and pills
Tabs show several panels in one place: one is visible, the others wait for a click on their label. In the admin dashboard settings are split this way into "Profile", "Team" and "Billing". Pills are the same tabs, but the labels look like rounded buttons.
Navigation without switching
First, just a row of links. The nav class on the list and nav-link on the links, while nav-tabs or nav-pills set the look:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<ul class="nav nav-tabs mb-3">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">All tasks</a></li>
<li class="nav-item"><a class="nav-link" href="#">Mine</a></li>
<li class="nav-item"><a class="nav-link" href="#">Overdue</a></li>
</ul>
<ul class="nav nav-pills">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Day</a></li>
<li class="nav-item"><a class="nav-link" href="#">Week</a></li>
</ul>At the top are tab labels with a line underneath, below are pills where the active one is filled blue. These are just links: each can lead to its own page. nav-fill stretches the items over the full width, flex-column stacks them.
Switchable panels
To make tabs switch content in place, the labels become buttons with data-bs-toggle="tab" and data-bs-target, and the panels go into tab-content:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-pane"
type="button" role="tab" aria-controls="profile-pane" aria-selected="true">Profile</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="billing-tab" data-bs-toggle="tab" data-bs-target="#billing-pane"
type="button" role="tab" aria-controls="billing-pane" aria-selected="false">Billing</button>
</li>
</ul>
<div class="tab-content border border-top-0 p-3">
<div class="tab-pane fade show active" id="profile-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">
Name: Anna Smith, email: anna@example.com
</div>
<div class="tab-pane fade" id="billing-pane" role="tabpanel" aria-labelledby="billing-tab" tabindex="0">
Team plan, next payment $90 on November 1.
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>The "Profile" tab is open. Click "Billing" and the text changes smoothly while the label becomes active. The page does not reload.
What is for what
| Attribute or class | Role |
|---|---|
data-bs-toggle="tab" or "pill" | The button switches a panel |
data-bs-target | The id of the panel to show |
tab-pane fade | A panel with a fade-in |
show active | The panel visible on load |
role, aria-* | Describe the tabs to screen readers |
Pills work the same way, only with nav-pills on the list and data-bs-toggle="pill" on the buttons.
Common mistake
Marking a label as active but forgetting show active on its panel — or the other way round. Bootstrap does not check anything on load: one tab is highlighted, while underneath there is nothing or another tab's panel. Always mark the active label and its panel as a pair.