Skip to content

Tabs

An accessible tabs component for organizing content into multiple panels.

Basic Usage

Account Settings

Manage your account details and preferences here.

Password Settings

Change your password and security options.

Notification Preferences

Configure how you receive notifications.

Vertical Tabs

Profile Information

Update your personal information and profile photo.

Billing Information

Manage your subscription and payment methods.

Team Management

Invite team members and manage permissions.

Manual Activation

Use activationMode: 'manual' to require explicit activation with Enter or click.

Overview content - Press Enter to activate tabs with keyboard.

Analytics content - Use arrow keys to navigate, Enter to select.

Reports content - Manual activation prevents accidental switching.

With x-model

Home content

About content

Contact content

Active tab:

Disabled State

General settings (disabled)

Advanced settings (disabled)

With Change Event

Content 1

Content 2

Content 3

API Reference

Component Props

PropTypeDefaultDescription
valuestring-ID of the active tab
orientation'horizontal' | 'vertical''horizontal'Tab list orientation
activationMode'automatic' | 'manual''automatic'How tabs are activated (on focus or on click/enter)
disabledbooleanfalseWhether the tabs are disabled
loopbooleantrueWhether arrow key navigation loops around

Parts

PartDescription
x-tabs:rootRoot container element
x-tabs:listTab list container (role="tablist")
x-tabs:trigger="id"Tab button (role="tab") with tab ID
x-tabs:content="id"Tab panel content (role="tabpanel") with tab ID
x-tabs:indicatorOptional visual indicator element

Data Attributes

AttributeDescription
data-disabledPresent when tabs are disabled
data-orientationCurrent orientation (horizontal or vertical)
data-stateTab state (active or inactive) on trigger and content
data-valueTab ID on trigger and content elements

Events

EventDetailDescription
change{ value }Fired when active tab changes

Keyboard Interactions

KeyDescription
TabMove focus into/out of tab list
ArrowRight / ArrowDownMove to next tab
ArrowLeft / ArrowUpMove to previous tab
HomeMove to first tab
EndMove to last tab
Enter / SpaceActivate focused tab (in manual mode)

Accessibility

This component follows the WAI-ARIA Tabs Pattern:

  • Uses role="tablist", role="tab", and role="tabpanel"
  • Provides aria-selected, aria-controls, and aria-labelledby attributes
  • Implements all required keyboard interactions
  • Only the active tab is in the focus order (tabindex="0")
  • Content panels are properly linked to their tabs

Styling

The tabs component is completely unstyled by default. Use data attributes to style different states:

css
/* Active tab */
[data-part="trigger"][data-state="active"] {
  /* Active tab styles */
}

/* Inactive tab */
[data-part="trigger"][data-state="inactive"] {
  /* Inactive tab styles */
}

/* Tab content */
[data-part="content"][data-state="active"] {
  /* Visible content styles */
}

/* Vertical orientation */
[data-orientation="vertical"] [data-part="list"] {
  /* Vertical tab list styles */
}

Tips

  • Each trigger and content must specify the same tab ID (e.g., x-tabs:trigger="'tab1'" and x-tabs:content="'tab1'")
  • Triggers should be placed inside x-tabs:list for proper keyboard navigation
  • Content elements can be placed anywhere in the component
  • Use data-state="active" attribute selector for styling active tabs
  • Set activationMode: 'manual' for tabs with potentially expensive content loading
  • The loop prop controls whether arrow key navigation wraps around
  • Content panels are hidden with the hidden attribute when inactive

Built with Alpine.js and inspired by Zag.js