Skip to main content
Vuetify0 is now a release candidate!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

Tabs

A component for creating accessible tabbed interfaces with proper ARIA support and keyboard navigation.

Usage

The Tabs component provides a compound pattern for building accessible tab interfaces. It uses the createStep composable internally for navigation and provides full v-model support with automatic state synchronization.

Profile

Content for the profile tab.

<script setup lang="ts">
  import { Tabs } from '@vuetify/v0'
  import { ref } from 'vue'

  const selected = ref('profile')

  const tabs = [
    { value: 'profile', label: 'Profile' },
    { value: 'password', label: 'Password' },
    { value: 'billing', label: 'Billing' },
  ]
</script>

<template>
  <div class="w-full">
    <Tabs.Root v-model="selected">
      <Tabs.List
        class="flex gap-1 border-b border-divider"
        label="Account settings"
      >
        <Tabs.Item
          v-for="tab in tabs"
          :key="tab.value"
          class="px-4 py-2 text-sm font-medium transition-colors -mb-px border-b-2 border-transparent text-on-surface-variant hover:text-on-surface hover:border-divider data-[selected]:border-primary data-[selected]:text-primary data-[selected]:hover:text-primary data-[selected]:hover:border-primary"
          :value="tab.value"
        >
          {{ tab.label }}
        </Tabs.Item>
      </Tabs.List>

      <Tabs.Panel
        v-for="tab in tabs"
        :key="tab.value"
        class="p-4"
        :value="tab.value"
      >
        <h3 class="text-lg font-medium mb-2">{{ tab.label }}</h3>

        <p class="text-on-surface-variant">
          Content for the {{ tab.label.toLowerCase() }} tab.
        </p>
      </Tabs.Panel>
    </Tabs.Root>
  </div>
</template>

Anatomy

vue
<script setup lang="ts">
  import { Tabs } from '@vuetify/v0'
</script>

<template>
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Item />
    </Tabs.List>

    <Tabs.Panel />
  </Tabs.Root>
</template>

Recipes

Activation Modes

Control when tabs activate with the activation prop:

  • automatic (default): Arrow keys move focus and activate the tab simultaneously

  • manual: Arrow keys move focus without activating — the user must press Enter or Space to confirm their selection

vue
<template>
  <Tabs.Root activation="manual">
    <!-- Tabs only activate on Enter/Space -->
  </Tabs.Root>
</template>

Orientation

Support for both horizontal and vertical tab layouts:

vue
<template>
  <Tabs.Root orientation="vertical">
    <!-- Arrow Up/Down for navigation instead of Left/Right -->
  </Tabs.Root>
</template>

Circular Navigation

Control whether navigation wraps around at boundaries:

vue
<template>
  <Tabs.Root :circular="false">
    <!-- Navigation stops at first/last tab -->
  </Tabs.Root>
</template>

Auto-Enrollment

Set enroll to auto-select the first registered tab. Useful when tabs are rendered dynamically and the initial selection should track whichever tab mounts first:

vue
<template>
  <Tabs.Root enroll>
    <!-- First tab to register is automatically selected -->
    <Tabs.Tab v-for="tab in dynamicTabs" :key="tab.id" :value="tab.id">
      {{ tab.label }}
    </Tabs.Tab>
  </Tabs.Root>
</template>

Accessibility

Keyboard Navigation

The component implements full WAI-ARIA keyboard support. Keyboard behavior depends on the activation mode:

KeyAutomaticManual
Arrow Left/Right (horizontal)Moves focus and activates tabMoves focus only
Arrow Up/Down (vertical)Moves focus and activates tabMoves focus only
HomeFocuses and activates first tabFocuses first tab only
EndFocuses and activates last tabFocuses last tab only
Enter/SpaceActivates the focused tab

FAQ

Discord
Need help? Join our community for support and discussions ↗

API Reference

The following API details are for all variations of the Tabs component.
Was this page helpful?

Ctrl+/