Skip to content

Tabs <l-tabs>

Tabs organize content into panels, showing one at a time. Progressive enhancement — plain HTML is enhanced with ARIA roles, keyboard navigation, and an animated indicator.

HTML tag<l-tabs>
Native HTML
Progressive
Custom
Shadow DOM
Progressive Custom Element

Options

Enclosed variant

Add variant="enclosed" for a pill-shaped tablist with a sliding background indicator.

Make changes to your account here.
Change your password here.
Manage your notification preferences.
Code
html
<l-tabs variant="enclosed">
  <div>
    <button name="account">Account</button>
    <button name="password">Password</button>
    <button name="notifications">Notifications</button>
  </div>
  <div class="p-4 text-sm text-color-secondary">Make changes to your account here.</div>
  <div class="p-4 text-sm text-color-secondary">Change your password here.</div>
  <div class="p-4 text-sm text-color-secondary">Manage your notification preferences.</div>
</l-tabs>

Line variant

Add variant="line" for a tablist with a sliding underline indicator.

Make changes to your account here.
Change your password here.
Manage your notification preferences.
Code
html
<l-tabs variant="line">
  <div>
    <button name="account">Account</button>
    <button name="password">Password</button>
    <button name="notifications">Notifications</button>
  </div>
  <div class="p-4 text-sm text-color-secondary">Make changes to your account here.</div>
  <div class="p-4 text-sm text-color-secondary">Change your password here.</div>
  <div class="p-4 text-sm text-color-secondary">Manage your notification preferences.</div>
</l-tabs>

Full width

Add full-width to stretch tabs across the container.

Make changes to your account here.
Change your password here.
Manage your notification preferences.
Code
html
<l-tabs
  variant="enclosed"
  full-width
>
  <div>
    <button name="account">Account</button>
    <button name="password">Password</button>
    <button name="notifications">Notifications</button>
  </div>
  <div class="p-4 text-sm text-color-secondary">Make changes to your account here.</div>
  <div class="p-4 text-sm text-color-secondary">Change your password here.</div>
  <div class="p-4 text-sm text-color-secondary">Manage your notification preferences.</div>
</l-tabs>

Default active tab

Set value="1" to activate a specific tab on load (0-based index).

Make changes to your account here.
Change your password here.
Manage your notification preferences.
Code
html
<l-tabs
  variant="enclosed"
  value="1"
>
  <div>
    <button name="account">Account</button>
    <button name="password">Password</button>
    <button name="notifications">Notifications</button>
  </div>
  <div class="p-4 text-sm text-color-secondary">Make changes to your account here.</div>
  <div class="p-4 text-sm text-color-secondary">Change your password here.</div>
  <div class="p-4 text-sm text-color-secondary">Manage your notification preferences.</div>
</l-tabs>

Accessibility

Criteria

Role

First child div gets role="tablist", buttons get role="tab", remaining divs get role="tabpanel"

WCAG4.1.2
RGAA7.1
Linked controls

Each tab has aria-controls pointing to its panel; each panel has aria-labelledby pointing back to its tab

WCAG1.3.1
Selection state

Active tab has aria-selected="true"; inactive tabs have aria-selected="false"

WCAG4.1.2
Focus management

Roving tabindex — active tab has tabindex="0", others tabindex="-1". Panels have tabindex="0" for keyboard access

WCAG2.1.1
RGAA12.13
Hidden content

Inactive panels use the hidden attribute

WCAG1.3.2
Motion

Indicator animation respects prefers-reduced-motion

WCAG2.3.3

Keyboard interactions

ArrowRight
Moves focus to the next tab and activates it (horizontal orientation)
ArrowLeft
Moves focus to the previous tab and activates it (horizontal orientation)
ArrowDown
Moves focus to the next tab and activates it (vertical orientation)
ArrowUp
Moves focus to the previous tab and activates it (vertical orientation)
Home
Moves focus to the first tab and activates it
End
Moves focus to the last tab and activates it
Tab
Moves focus out of the tablist to the active panel

API reference

Importing

js
import 'luxen-ui/tabs';
css
@import 'luxen-ui/css/tabs/enclosed';
css
@import 'luxen-ui/css/tabs/line';

Attributes & Properties

variant="enclosed"Attribute
Pill-shaped tablist with sliding background indicator
variant="line"Attribute
Tablist with sliding underline indicator
valueAttribute
Active tab index (0-based string). Default "0"
full-widthAttribute
Stretches tabs to fill the container width
orientation="horizontal"Attribute
Horizontal tab layout (default). Arrow Left/Right navigate
orientation="vertical"Attribute
Vertical tab layout. Arrow Up/Down navigate

Events

changeEvent
Fires when the active tab changes. e.detail.index (number) and e.detail.name (button name attribute or null)

CSS custom properties

--_durationName
Indicator animation duration (default: 150ms, 0ms with reduced motion)
--_easingName
Indicator animation easing (default: cubic-bezier(0.25, 0.1, 0.25, 1))