Skip to component content

Switch between compact operational views with Bootstrap's native tab behavior.

Tabs use a stable panel height by default. Set height="content" when each view should take only the space its active content needs.

Connected panels

Each trigger points at one tab panel and the active panel stays visible.

Keep labels short so the tab list remains quick to scan.

Click activation

A tab changes state only after it is selected by click or keyboard.

Hover can hint at interactivity without looking like the active tab.

Panel content

Use panels for peer views that can be shown one at a time.

Keep required sequential steps outside inactive tabs.

Usage

Use .nav-tabs or .nav-pills for peer panels where one view should be visible at a time. Connect each tab trigger to exactly one .tab-pane, keep labels short, and keep the selected trigger and visible panel in sync with Bootstrap's tab behavior.

Tabs should activate when selected by click or keyboard, not merely on hover. Hover can show a subtle affordance, but the active visual state belongs only to the selected tab and its panel.

Use horizontal tabs for compact peer views and vertical tabs when labels scan better as a side rail. Keep required sequential steps outside inactive panels, because hidden tab content should not block users from completing the current task.

Operational views

Use tab sets when users need to move between related operational surfaces quickly.

Tabs
Track open requests, risk flags, and handoff status.
Move items through review lanes with minimal context switching.
Set locale, notifications, and digest frequency from one place.
<div class="tabs">
  <div class="tabs-list nav nav-pills" id="tabs-operational-list" role="tablist">
    <button class="nav-link active" id="tabs-operational-overview-tab" data-bs-toggle="tab" data-bs-target="#tabs-operational-overview-pane" type="button" role="tab" aria-controls="tabs-operational-overview-pane" aria-selected="true">Overview</button>
    <button class="nav-link" id="tabs-operational-workflows-tab" data-bs-toggle="tab" data-bs-target="#tabs-operational-workflows-pane" type="button" role="tab" aria-controls="tabs-operational-workflows-pane" aria-selected="false">Workflows</button>
    <button class="nav-link" id="tabs-operational-settings-tab" data-bs-toggle="tab" data-bs-target="#tabs-operational-settings-pane" type="button" role="tab" aria-controls="tabs-operational-settings-pane" aria-selected="false">Settings</button>
  </div>
  <div class="tab-content" id="tabs-operational-content">
    <div class="tab-pane fade show active" id="tabs-operational-overview-pane" role="tabpanel" aria-labelledby="tabs-operational-overview-tab" tabindex="0">Track open requests, risk flags, and handoff status.</div>
    <div class="tab-pane fade" id="tabs-operational-workflows-pane" role="tabpanel" aria-labelledby="tabs-operational-workflows-tab" tabindex="0">Move items through review lanes with minimal context switching.</div>
    <div class="tab-pane fade" id="tabs-operational-settings-pane" role="tabpanel" aria-labelledby="tabs-operational-settings-tab" tabindex="0">Set locale, notifications, and digest frequency from one place.</div>
  </div>
</div>

Vertical

Set orientation="vertical" when the tab triggers should stack beside the active panel.

Tabs

Stacked triggers

Use a vertical tab list when labels scan better as a short side rail.

The tablist keeps the same tab roles while adding vertical orientation.

Keyboard state

Bootstrap keeps one active tab in the roving focus order.

The selected trigger and visible panel update together after activation.

Panel width

Let the active panel use the remaining inline space.

Keep each panel self-contained so switching tabs does not require extra context.

<div class="moo-example__preview-frame moo-example__preview-frame--wide">
  <div class="tabs tabs--vertical">
    <div class="tabs-list nav nav-pills flex-column" id="tabs-vertical-list" role="tablist" aria-orientation="vertical">
      <button class="nav-link active" id="tabs-vertical-structure-tab" data-bs-toggle="pill" data-bs-target="#tabs-vertical-structure-pane" type="button" role="tab" aria-controls="tabs-vertical-structure-pane" aria-selected="true">Structure</button>
      <button class="nav-link" id="tabs-vertical-keyboard-tab" data-bs-toggle="pill" data-bs-target="#tabs-vertical-keyboard-pane" type="button" role="tab" aria-controls="tabs-vertical-keyboard-pane" aria-selected="false">Keyboard</button>
      <button class="nav-link" id="tabs-vertical-panels-tab" data-bs-toggle="pill" data-bs-target="#tabs-vertical-panels-pane" type="button" role="tab" aria-controls="tabs-vertical-panels-pane" aria-selected="false">Panels</button>
    </div>
    <div class="tab-content" id="tabs-vertical-content">
      <div class="tab-pane fade show active" id="tabs-vertical-structure-pane" role="tabpanel" aria-labelledby="tabs-vertical-structure-tab" tabindex="0">
        <div class="card card--sm">
          <div class="card-header">
            <div class="card-header__text">
              <h3 class="card-title">Stacked triggers</h3>
              <p class="card-subtitle">Use a vertical tab list when labels scan better as a short side rail.</p>
            </div>
          </div>
          <div class="card-body">
            <p class="mb-0 text-body-secondary">The tablist keeps the same tab roles while adding vertical orientation.</p>
          </div>
        </div>
      </div>
      <div class="tab-pane fade" id="tabs-vertical-keyboard-pane" role="tabpanel" aria-labelledby="tabs-vertical-keyboard-tab" tabindex="0">
        <div class="card card--sm">
          <div class="card-header">
            <div class="card-header__text">
              <h3 class="card-title">Keyboard state</h3>
              <p class="card-subtitle">Bootstrap keeps one active tab in the roving focus order.</p>
            </div>
          </div>
          <div class="card-body">
            <p class="mb-0 text-body-secondary">The selected trigger and visible panel update together after activation.</p>
          </div>
        </div>
      </div>
      <div class="tab-pane fade" id="tabs-vertical-panels-pane" role="tabpanel" aria-labelledby="tabs-vertical-panels-tab" tabindex="0">
        <div class="card card--sm">
          <div class="card-header">
            <div class="card-header__text">
              <h3 class="card-title">Panel width</h3>
              <p class="card-subtitle">Let the active panel use the remaining inline space.</p>
            </div>
          </div>
          <div class="card-body">
            <p class="mb-0 text-body-secondary">Keep each panel self-contained so switching tabs does not require extra context.</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Disabled

Set disabled on an item to remove it from keyboard and pointer interaction.

Tabs
Open requests can be edited and reassigned from here.
Historical items stay locked for audit safety.
Completed cases remain searchable in read-only mode.
<div class="tabs">
  <div class="tabs-list nav nav-pills" id="tabs-disabled-list" role="tablist">
    <button class="nav-link active" id="tabs-disabled-active-tab" data-bs-toggle="tab" data-bs-target="#tabs-disabled-active-pane" type="button" role="tab" aria-controls="tabs-disabled-active-pane" aria-selected="true">Active</button>
    <button class="nav-link" id="tabs-disabled-locked-tab" data-bs-toggle="tab" data-bs-target="#tabs-disabled-locked-pane" type="button" role="tab" aria-controls="tabs-disabled-locked-pane" aria-selected="false" disabled>Locked</button>
    <button class="nav-link" id="tabs-disabled-archive-tab" data-bs-toggle="tab" data-bs-target="#tabs-disabled-archive-pane" type="button" role="tab" aria-controls="tabs-disabled-archive-pane" aria-selected="false">Archive</button>
  </div>
  <div class="tab-content" id="tabs-disabled-content">
    <div class="tab-pane fade show active" id="tabs-disabled-active-pane" role="tabpanel" aria-labelledby="tabs-disabled-active-tab" tabindex="0">Open requests can be edited and reassigned from here.</div>
    <div class="tab-pane fade" id="tabs-disabled-locked-pane" role="tabpanel" aria-labelledby="tabs-disabled-locked-tab" tabindex="0">Historical items stay locked for audit safety.</div>
    <div class="tab-pane fade" id="tabs-disabled-archive-pane" role="tabpanel" aria-labelledby="tabs-disabled-archive-tab" tabindex="0">Completed cases remain searchable in read-only mode.</div>
  </div>
</div>

RTL

RTL

لوحات مرتبطة

يشير كل تبويب إلى لوحة محتوى واحدة وتبقى اللوحة النشطة ظاهرة.

اجعل عناوين التبويبات قصيرة حتى تبقى سهلة المسح.

تفعيل بالنقر

يتغير التبويب النشط فقط بعد اختياره بالنقر أو لوحة المفاتيح.

يبقى التحويم خفيفا ولا يبدو كأنه الحالة النشطة.

محتوى اللوحة

استخدم اللوحات لواجهات متوازية تظهر واحدة في كل مرة.

اترك الخطوات المطلوبة خارج التبويبات غير النشطة.

<div dir="rtl">
  <div class="moo-example__preview-frame">
    <div class="tabs">
      <div class="tabs-list nav nav-pills" id="tabs-rtl-overview-arabic-list" role="tablist">
        <button class="nav-link active" id="tabs-rtl-overview-arabic-overview-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-arabic-overview-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-arabic-overview-pane" aria-selected="true">نظرة عامة</button>
        <button class="nav-link" id="tabs-rtl-overview-arabic-activation-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-arabic-activation-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-arabic-activation-pane" aria-selected="false">التفعيل</button>
        <button class="nav-link" id="tabs-rtl-overview-arabic-panels-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-arabic-panels-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-arabic-panels-pane" aria-selected="false">اللوحات</button>
      </div>
      <div class="tab-content" id="tabs-rtl-overview-arabic-content">
        <div class="tab-pane fade show active" id="tabs-rtl-overview-arabic-overview-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-arabic-overview-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">لوحات مرتبطة</h3>
                <p class="card-subtitle">يشير كل تبويب إلى لوحة محتوى واحدة وتبقى اللوحة النشطة ظاهرة.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">اجعل عناوين التبويبات قصيرة حتى تبقى سهلة المسح.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-arabic-activation-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-arabic-activation-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">تفعيل بالنقر</h3>
                <p class="card-subtitle">يتغير التبويب النشط فقط بعد اختياره بالنقر أو لوحة المفاتيح.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">يبقى التحويم خفيفا ولا يبدو كأنه الحالة النشطة.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-arabic-panels-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-arabic-panels-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">محتوى اللوحة</h3>
                <p class="card-subtitle">استخدم اللوحات لواجهات متوازية تظهر واحدة في كل مرة.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">اترك الخطوات المطلوبة خارج التبويبات غير النشطة.</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

פאנלים מחוברים

כל טריגר מצביע אל פאנל תוכן אחד והפאנל הפעיל נשאר גלוי.

שמור על תוויות קצרות כדי שרשימת הטאבים תיסרק במהירות.

הפעלה בלחיצה

טאב משנה מצב רק אחרי בחירה בלחיצה או במקלדת.

ריחוף נשאר עדין ולא נראה כמו הטאב הפעיל.

תוכן הפאנל

השתמש בפאנלים עבור תצוגות מקבילות שמופיעות אחת בכל פעם.

השאר שלבים הכרחיים מחוץ לטאבים לא פעילים.

<div dir="rtl">
  <div class="moo-example__preview-frame">
    <div class="tabs">
      <div class="tabs-list nav nav-pills" id="tabs-rtl-overview-hebrew-list" role="tablist">
        <button class="nav-link active" id="tabs-rtl-overview-hebrew-overview-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-hebrew-overview-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-hebrew-overview-pane" aria-selected="true">סקירה כללית</button>
        <button class="nav-link" id="tabs-rtl-overview-hebrew-activation-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-hebrew-activation-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-hebrew-activation-pane" aria-selected="false">הפעלה</button>
        <button class="nav-link" id="tabs-rtl-overview-hebrew-panels-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-hebrew-panels-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-hebrew-panels-pane" aria-selected="false">פאנלים</button>
      </div>
      <div class="tab-content" id="tabs-rtl-overview-hebrew-content">
        <div class="tab-pane fade show active" id="tabs-rtl-overview-hebrew-overview-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-hebrew-overview-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">פאנלים מחוברים</h3>
                <p class="card-subtitle">כל טריגר מצביע אל פאנל תוכן אחד והפאנל הפעיל נשאר גלוי.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">שמור על תוויות קצרות כדי שרשימת הטאבים תיסרק במהירות.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-hebrew-activation-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-hebrew-activation-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">הפעלה בלחיצה</h3>
                <p class="card-subtitle">טאב משנה מצב רק אחרי בחירה בלחיצה או במקלדת.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">ריחוף נשאר עדין ולא נראה כמו הטאב הפעיל.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-hebrew-panels-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-hebrew-panels-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">תוכן הפאנל</h3>
                <p class="card-subtitle">השתמש בפאנלים עבור תצוגות מקבילות שמופיעות אחת בכל פעם.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">השאר שלבים הכרחיים מחוץ לטאבים לא פעילים.</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Connected panels

Each trigger points at one tab panel and the active panel stays visible.

Keep labels short so the tab list remains quick to scan.

Click activation

A tab changes state only after it is selected by click or keyboard.

Hover can hint at interactivity without looking like the active tab.

Panel content

Use panels for peer views that can be shown one at a time.

Keep required sequential steps outside inactive tabs.

<div dir="ltr">
  <div class="moo-example__preview-frame">
    <div class="tabs">
      <div class="tabs-list nav nav-pills" id="tabs-rtl-overview-english-list" role="tablist">
        <button class="nav-link active" id="tabs-rtl-overview-english-overview-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-english-overview-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-english-overview-pane" aria-selected="true">Overview</button>
        <button class="nav-link" id="tabs-rtl-overview-english-activation-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-english-activation-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-english-activation-pane" aria-selected="false">Activation</button>
        <button class="nav-link" id="tabs-rtl-overview-english-panels-tab" data-bs-toggle="tab" data-bs-target="#tabs-rtl-overview-english-panels-pane" type="button" role="tab" aria-controls="tabs-rtl-overview-english-panels-pane" aria-selected="false">Panels</button>
      </div>
      <div class="tab-content" id="tabs-rtl-overview-english-content">
        <div class="tab-pane fade show active" id="tabs-rtl-overview-english-overview-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-english-overview-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">Connected panels</h3>
                <p class="card-subtitle">Each trigger points at one tab panel and the active panel stays visible.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">Keep labels short so the tab list remains quick to scan.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-english-activation-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-english-activation-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">Click activation</h3>
                <p class="card-subtitle">A tab changes state only after it is selected by click or keyboard.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">Hover can hint at interactivity without looking like the active tab.</p>
            </div>
          </div>
        </div>
        <div class="tab-pane fade" id="tabs-rtl-overview-english-panels-pane" role="tabpanel" aria-labelledby="tabs-rtl-overview-english-panels-tab" tabindex="0">
          <div class="card card--sm">
            <div class="card-header">
              <div class="card-header__text">
                <h3 class="card-title">Panel content</h3>
                <p class="card-subtitle">Use panels for peer views that can be shown one at a time.</p>
              </div>
            </div>
            <div class="card-body">
              <p class="mb-0 text-body-secondary">Keep required sequential steps outside inactive tabs.</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Component reference

Status
Accepted
Runtime
Bootstrap plugin
Markup
Bootstrap/native HTML
Reference

For Bootstrap's Tab plugin behavior and keyboard interaction, see the Bootstrap Navs and tabs documentation.

Settings

Theme
Choose how Moo UI looks on this device.
Sidebar
Choose how the sidebar sits on the page.
Theme Builder
Tune catalog tokens and chart colors for this browser.
Base color
Theme color
Chart color
Heading font
Body font
Radius
Direction
Choose the reading direction. RTL flips the layout live.
Reset

Restore the default appearance.