Skip to documentation
BoobstrapDocs
Interactivity

Tabs

Organize related panels with automatic activation, roving focus, and synchronized ARIA state.

Interactivity guideCopy-ready referencev0.7.0 current
Interactivity

Tabs

Tabs use automatic activation and a roving tabindex. Horizontal lists use Left/Right; vertical lists use Up/Down. Both support Home and End.

Profile settings
HTML · Boobstrap JS
<div class="bs-tabs" role="tablist" aria-label="Account" data-bs-tabs>
  <button class="bs-tab" id="profile-tab" type="button" role="tab"
    aria-controls="profile-panel" aria-selected="true">Profile</button>
  <button class="bs-tab" id="security-tab" type="button" role="tab"
    aria-controls="security-panel">Security</button>
</div>
<div class="bs-tab-panel" id="profile-panel" role="tabpanel"
  aria-labelledby="profile-tab">Profile settings</div>
<div class="bs-tab-panel" id="security-panel" role="tabpanel"
  aria-labelledby="security-tab" hidden>Security settings</div>

Structure

Each tab's aria-controls and panel's aria-labelledby form a two-way relationship.

State

The selected tab gets aria-selected="true"; every inactive panel uses hidden.

Accessibility

Use tabs only when panels are peer views. Preserve meaningful headings inside complex panels.

Pill tabs

Use the pills modifier for a compact view switcher. It changes presentation only; the same tab roles, relationships, and controller behavior still apply.

7-day report
HTML · Pill tabs
<div class="bs-tabs bs-tabs-pills" role="tablist" aria-label="Report period" data-bs-tabs>
  <button class="bs-tab" id="pill-week-tab" type="button" role="tab" aria-controls="pill-week-panel" aria-selected="true">Week</button>
  <button class="bs-tab" id="pill-month-tab" type="button" role="tab" aria-controls="pill-month-panel">Month</button>
</div>
<div class="bs-tab-panel" id="pill-week-panel" role="tabpanel" aria-labelledby="pill-week-tab">7-day report</div>
<div class="bs-tab-panel" id="pill-month-panel" role="tabpanel" aria-labelledby="pill-month-tab" hidden>30-day report</div>

Contained tabs and panels

Pair contained tabs with contained panels when the selector and content should read as one bordered surface.

Deployment completed successfully.
HTML · Contained tabs
<section aria-label="Deployment details">
  <div class="bs-tabs bs-tabs-contained" role="tablist" aria-label="Deployment detail" data-bs-tabs>
    <button class="bs-tab" id="contained-summary-tab" type="button" role="tab" aria-controls="contained-summary-panel" aria-selected="true">Summary</button>
    <button class="bs-tab" id="contained-log-tab" type="button" role="tab" aria-controls="contained-log-panel">Build log</button>
  </div>
  <div class="bs-tab-panel bs-tab-panel-contained" id="contained-summary-panel" role="tabpanel" aria-labelledby="contained-summary-tab">Deployment completed successfully.</div>
  <div class="bs-tab-panel bs-tab-panel-contained" id="contained-log-panel" role="tabpanel" aria-labelledby="contained-log-tab" hidden>Build finished in 42 seconds.</div>
</section>

Initialize and observe tabs

The tabs controller synchronizes selection, panel visibility, roving focus, and change events.

JavaScript · Initialization and events
import { initBoobstrap } from "@boobstrap/boobstrap/js";

const boobstrap = initBoobstrap(document);
const tablist = document.querySelector("[data-bs-tabs]");

tablist.addEventListener("bs:tabs:changed", (event) => {
  console.log("Selected tab", event.detail.tab.id);
});

// Later: boobstrap.destroy();

Tab presentation classes

Presentation modifiers do not change tab semantics or behavior. Apply them to the base tablist and panel classes while keeping every ARIA relationship intact.

ClassPurpose
.bs-tabs-pillsTurns the base tablist into a compact pill-style view switcher.
.bs-tabs-containedConnects the tablist visually to a bordered content surface.
.bs-tab-panel-containedAdds the matching border, surface, radius, and padding to each controlled panel.

JavaScript API

Import Tabs from @boobstrap/boobstrap/js/tabs.

ContractPurpose
activate(tab)Select a tab element and synchronize all controlled panels.
bs:tabs:changeCancelable before-event with previous and next tab/panel detail.
bs:tabs:changedBubbling event after the completed transition.