v1.1.1

Tabs

A set of layered sections of content — known as tab panels — that are displayed one at a time.

Interactive Requires: veritheme.js JS init: automatic

Default

Pill-style tabs with a muted background container.

html

Account

Make changes to your account here.

Password

Change your password here.

Settings

Manage your application preferences.

<div class="vt-w-full vt-max-w-md">
  <div data-tab-group="default">
    <div role="tablist" aria-label="Account settings" class="vt-tabs-list vt-w-full">
      <button role="tab" aria-selected="true" aria-controls="panel-default-account" id="tab-default-account" data-tab="account" class="vt-tabs-trigger vt-active vt-flex-1" tabindex="0">Account</button>
      <button role="tab" aria-selected="false" aria-controls="panel-default-password" id="tab-default-password" data-tab="password" class="vt-tabs-trigger vt-flex-1" tabindex="-1">Password</button>
      <button role="tab" aria-selected="false" aria-controls="panel-default-settings" id="tab-default-settings" data-tab="settings" class="vt-tabs-trigger vt-flex-1" tabindex="-1">Settings</button>
    </div>
    <div role="tabpanel" id="panel-default-account" aria-labelledby="tab-default-account" data-panel="account" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6" tabindex="0">
      <h3 class="vt-text-base vt-font-semibold vt-mb-1">Account</h3>
      <p class="vt-text-sm vt-text-foreground-muted vt-mb-4">Make changes to your account here.</p>
      <div class="vt-space-y-4">
        <div class="vt-space-y-2">
          <label class="vt-label" for="tabs-1-1">
            Name
          </label>
          <input type="text" value="John Doe" class="vt-input" id="tabs-1-1">
        </div>
        <div class="vt-space-y-2">
          <label class="vt-label" for="tabs-1-2">
            Username
          </label>
          <input type="text" value="@johndoe" class="vt-input" id="tabs-1-2">
        </div>
        <button class="vt-btn vt-btn-primary">
          Save changes
        </button>
      </div>
    </div>
    <div role="tabpanel" id="panel-default-password" aria-labelledby="tab-default-password" data-panel="password" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6 vt-hidden" tabindex="0">
      <h3 class="vt-text-base vt-font-semibold vt-mb-1">Password</h3>
      <p class="vt-text-sm vt-text-foreground-muted vt-mb-4">Change your password here.</p>
      <div class="vt-space-y-4">
        <div class="vt-space-y-2">
          <label class="vt-label" for="tabs-1-3">
            Current password
          </label>
          <input type="password" class="vt-input" id="tabs-1-3">
        </div>
        <div class="vt-space-y-2">
          <label class="vt-label" for="tabs-1-4">
            New password
          </label>
          <input type="password" class="vt-input" id="tabs-1-4">
        </div>
        <button class="vt-btn vt-btn-primary">
          Save password
        </button>
      </div>
    </div>
    <div role="tabpanel" id="panel-default-settings" aria-labelledby="tab-default-settings" data-panel="settings" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6 vt-hidden" tabindex="0">
      <h3 class="vt-text-base vt-font-semibold vt-mb-1">Settings</h3>
      <p class="vt-text-sm vt-text-foreground-muted">Manage your application preferences.</p>
    </div>
  </div>
</div>

Default With Icons

Pill-style tabs with icons alongside labels.

html

Manage your account details and preferences.

Update your password and security settings.

Control how and when you receive notifications.

<div class="vt-w-full vt-max-w-md">
  <div data-tab-group="default-icons">
    <div role="tablist" aria-label="Settings" class="vt-tabs-list vt-w-full">
      <button role="tab" aria-selected="true" aria-controls="panel-default-icons-account" id="tab-default-icons-account" data-tab="account" class="vt-tabs-trigger vt-active vt-gap-1.5 vt-flex-1" tabindex="0">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-user vt-w-4 vt-h-4">
          <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>
        </svg>Account
      </button>
      <button role="tab" aria-selected="false" aria-controls="panel-default-icons-security" id="tab-default-icons-security" data-tab="security" class="vt-tabs-trigger vt-gap-1.5 vt-flex-1" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-lock vt-w-4 vt-h-4">
          <rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
        </svg>Security
      </button>
      <button role="tab" aria-selected="false" aria-controls="panel-default-icons-notifications" id="tab-default-icons-notifications" data-tab="notifications" class="vt-tabs-trigger vt-gap-1.5 vt-flex-1" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-bell vt-w-4 vt-h-4">
          <path d="M10.268 21a2 2 0 0 0 3.464 0"></path><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"></path>
        </svg>Notifications
      </button>
    </div>
    <div role="tabpanel" id="panel-default-icons-account" aria-labelledby="tab-default-icons-account" data-panel="account" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Manage your account details and preferences.</p>
    </div>
    <div role="tabpanel" id="panel-default-icons-security" aria-labelledby="tab-default-icons-security" data-panel="security" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Update your password and security settings.</p>
    </div>
    <div role="tabpanel" id="panel-default-icons-notifications" aria-labelledby="tab-default-icons-notifications" data-panel="notifications" class="vt-mt-4 vt-card vt-bg-surface-card vt-p-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Control how and when you receive notifications.</p>
    </div>
  </div>
</div>

Underline

Tab style with a bottom-border indicator instead of a pill background.

html

Overview content. This tab shows general information about your project.

Analytics content. Track your project's performance metrics here.

Reports content. Generate and view detailed reports.

<div class="vt-w-full vt-max-w-md">
  <div data-tab-group="underline">
    <div role="tablist" aria-label="Project sections" class="vt-tabs-list-underline">
      <button role="tab" aria-selected="true" aria-controls="panel-underline-overview" id="tab-underline-overview" data-tab="overview" class="vt-tabs-trigger-underline vt-active" tabindex="0">Overview</button>
      <button role="tab" aria-selected="false" aria-controls="panel-underline-analytics" id="tab-underline-analytics" data-tab="analytics" class="vt-tabs-trigger-underline" tabindex="-1">Analytics</button>
      <button role="tab" aria-selected="false" aria-controls="panel-underline-reports" id="tab-underline-reports" data-tab="reports" class="vt-tabs-trigger-underline" tabindex="-1">Reports</button>
    </div>
    <div role="tabpanel" id="panel-underline-overview" aria-labelledby="tab-underline-overview" data-panel="overview" class="vt-py-6" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Overview content. This tab shows general information about your project.</p>
    </div>
    <div role="tabpanel" id="panel-underline-analytics" aria-labelledby="tab-underline-analytics" data-panel="analytics" class="vt-py-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Analytics content. Track your project's performance metrics here.</p>
    </div>
    <div role="tabpanel" id="panel-underline-reports" aria-labelledby="tab-underline-reports" data-panel="reports" class="vt-py-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Reports content. Generate and view detailed reports.</p>
    </div>
  </div>
</div>

Underline With Icons

Underline tabs with icons alongside labels.

html

Overview content. General information about your dashboard.

Analytics content. Track performance metrics here.

Reports content. Generate and view detailed reports.

<div class="vt-w-full vt-max-w-md">
  <div data-tab-group="underline-icons">
    <div role="tablist" aria-label="Dashboard sections" class="vt-tabs-list-underline">
      <button role="tab" aria-selected="true" aria-controls="panel-underline-icons-overview" id="tab-underline-icons-overview" data-tab="overview" class="vt-tabs-trigger-underline vt-active vt-inline-flex vt-items-center vt-gap-1.5" tabindex="0">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-user vt-w-4 vt-h-4">
          <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>
        </svg>Overview
      </button>
      <button role="tab" aria-selected="false" aria-controls="panel-underline-icons-analytics" id="tab-underline-icons-analytics" data-tab="analytics" class="vt-tabs-trigger-underline vt-inline-flex vt-items-center vt-gap-1.5" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-bell vt-w-4 vt-h-4">
          <path d="M10.268 21a2 2 0 0 0 3.464 0"></path><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"></path>
        </svg>Analytics
      </button>
      <button role="tab" aria-selected="false" aria-controls="panel-underline-icons-reports" id="tab-underline-icons-reports" data-tab="reports" class="vt-tabs-trigger-underline vt-inline-flex vt-items-center vt-gap-1.5" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-lock vt-w-4 vt-h-4">
          <rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
        </svg>Reports
      </button>
    </div>
    <div role="tabpanel" id="panel-underline-icons-overview" aria-labelledby="tab-underline-icons-overview" data-panel="overview" class="vt-py-6" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Overview content. General information about your dashboard.</p>
    </div>
    <div role="tabpanel" id="panel-underline-icons-analytics" aria-labelledby="tab-underline-icons-analytics" data-panel="analytics" class="vt-py-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Analytics content. Track performance metrics here.</p>
    </div>
    <div role="tabpanel" id="panel-underline-icons-reports" aria-labelledby="tab-underline-icons-reports" data-panel="reports" class="vt-py-6 vt-hidden" tabindex="0">
      <p class="vt-text-sm vt-text-foreground-muted">Reports content. Generate and view detailed reports.</p>
    </div>
  </div>
</div>

Guidelines

Switching content views in place (same page context). Page navigation → nav-item/link; compact display-mode toggles → button-group or mode-btn.

Do
Keep exactly one tab active to mark the current view.
Don't
Don't highlight multiple tabs as active at the same time.

Anatomy

HTML structure of the Tabs component.

div[data-tab-group]                     ← Scoping wrapper
├── div[role="tablist"]                  ← Tab buttons container
│   ├── button[role="tab"]               ← Tab button (active)
│   └── button[role="tab"]               ← Tab button (inactive)
├── div[role="tabpanel"]                 ← Visible panel
└── div[role="tabpanel"].vt-hidden        ← Hidden panel

API Reference

All CSS classes available for the Tabs component.

Class Type Description
role="tablist" Base Container for tab buttons — pill or underline style
role="tab" Base Individual tab button
role="tabpanel" Base Content panel associated with a tab
vt-bg-surface-moderate vt-p-1 vt-rounded-lg Variant Default (pill) tablist container
vt-border-b vt-border-border-default Variant Underline tablist container
vt-bg-surface-card vt-shadow-sm State Active tab in default style
vt-border-b-2 vt-border-info-fill State Active tab underline indicator
data-tab-group Modifier HTML attribute on wrapper — scopes tab switching
data-tab / data-panel Modifier HTML attributes linking tabs to their panels

Accessibility

Keyboard and screen reader support.

Feature Details
Roles tablist, tab, and tabpanel roles for proper semantics
Selection aria-selected="true" on the active tab
Association aria-controls and aria-labelledby link tabs to panels
Keyboard Arrow keys move between tabs, Home/End jump to first/last
Focus Only the active tab is in tab order (tabindex="0"), others are tabindex="-1"