Tabs
Tabbed content navigation with keyboard support and ARIA roles.
<arc-tabs> Overview
>
Tabs organize related content into separate panels that share the same page space. Only one panel is visible at a time, letting users switch context without navigating away. This makes Tabs ideal for grouping settings pages, documentation sections, or dashboard views where horizontal real estate is limited.
The component follows the WAI-ARIA Tabs pattern out of the box. Each tab button carries `role="tab"` and its corresponding panel carries `role="tabpanel"`, linked via `aria-controls` and `aria-labelledby`. Focus management uses a roving tabindex so arrow keys move between tabs while Tab moves focus out of the tab list entirely, matching the behavior users expect from native OS tab controls.
Transitions between panels are handled with a crossfade animation driven by CSS, keeping the switch feeling instantaneous on fast machines while remaining smooth on lower-end hardware. Panels that are not active are removed from the accessibility tree and hidden with `display: none` so screen readers never encounter stale content.Guidelines
When to use
- Use Tabs when content sections are closely related and users need to compare or switch between them frequently
- Keep tab labels short — one or two words — so the entire tab bar fits without scrolling
- Set a sensible default `selected` index (usually 0) so the component is never empty on first render
- Provide meaningful panel content for every tab; avoid empty or placeholder panels in production
- Use the disabled state for tabs that are temporarily unavailable rather than hiding them entirely
When not to use
- Do not use Tabs for sequential steps — use a Stepper component instead
- Avoid nesting Tabs inside Tabs; the double tab bar creates confusion for keyboard and screen-reader users
- Do not place critical actions (like a Save button) inside a non-default tab where users may never see them
- Avoid more than five or six tabs in a single group — consider a dropdown or sidebar navigation for larger sets
- Do not rely on tab order to imply a workflow; tabs should be independently meaningful
Features
- Arrow-key keyboard navigation between tabs (left/right for horizontal, up/down for vertical)
- Automatic WAI-ARIA roles: tab, tablist, and tabpanel with proper `aria-controls` linking
- Smooth crossfade transition when switching panels
- Disabled tab support — individual tabs can be non-interactive while remaining visible
- Programmatic selected index via the `selected` property
- Roving tabindex so only the active tab participates in the page Tab order
- Supports rich HTML content inside each panel, not just plain text
Preview
Usage
Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.
<arc-tabs>
<arc-tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</arc-tab>
<arc-tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</arc-tab>
<arc-tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</arc-tab>
</arc-tabs> import { Tabs, Tab } from '@arclux/arc-ui-react';
export default function Example() {
return (
<Tabs>
<Tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</Tab>
<Tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</Tab>
<Tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</Tab>
</Tabs>
);
} <script setup>
import { Tabs, Tab } from '@arclux/arc-ui-vue';
</script>
<template>
<Tabs>
<Tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</Tab>
<Tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</Tab>
<Tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</Tab>
</Tabs>
</template> <script>
import { Tabs, Tab } from '@arclux/arc-ui-svelte';
</script>
<Tabs>
<Tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</Tab>
<Tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</Tab>
<Tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</Tab>
</Tabs> import { Component } from '@angular/core';
import { Tabs, Tab } from '@arclux/arc-ui-angular';
@Component({
imports: [Tabs, Tab],
template: `
<arc-tabs>
<arc-tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</arc-tab>
<arc-tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</arc-tab>
<arc-tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</arc-tab>
</arc-tabs>
`,
})
export class TabsDemoComponent {} import { Tabs, Tab } from '@arclux/arc-ui-solid';
export default function TabsDemo() {
return (
<Tabs>
<Tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</Tab>
<Tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</Tab>
<Tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</Tab>
</Tabs>
);
} import { Tabs, Tab } from '@arclux/arc-ui-preact';
export default function TabsDemo() {
return (
<Tabs>
<Tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</Tab>
<Tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</Tab>
<Tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</Tab>
</Tabs>
);
} <arc-tabs>
<arc-tab label="Overview">
ARC UI is a framework-agnostic component library built on web standards.
</arc-tab>
<arc-tab label="Features">
Keyboard navigation, ARIA roles, smooth transitions, and lazy rendering.
</arc-tab>
<arc-tab label="Changelog">
v2.4.0 — Disabled tab support and improved focus-visible ring styling.
</arc-tab>
</arc-tabs> API
-
selectednumber0 - Zero-based index of the currently active tab. Changing this value programmatically switches the visible panel and updates ARIA attributes. Out-of-range values are clamped to the nearest valid index.
-
align'start' | 'center' | 'end''start' - Aligns the tab list. Options: 'start', 'center', 'end'.
-
variant'underline' | 'pills''underline' - Visual style of the tabs. Options: 'underline', 'pills'.
-
orientation'horizontal' | 'vertical''horizontal' - Layout direction of the tab list. Use 'vertical' to place tabs in a sidebar column with the panel to the right. Arrow-key navigation automatically switches to up/down in vertical mode.
Events
-
arc-change - Fired when the active tab changes
Tab
<arc-tab> An individual tab panel within a Tabs group. Each Tab renders a button in the tab bar and owns its associated content panel. Use this sub-component when you need fine-grained control over individual tab behavior, such as disabling a specific tab or attaching per-tab event listeners.
-
labelstring'' - Text displayed on the tab button. Keep labels concise — one or two words — to prevent the tab bar from overflowing.
See Also
- Accordion Expandable content sections with smooth height animations. Ideal for FAQs, settings panels, and any UI that benefits from progressive disclosure.
- Segmented Control A radio-group-style toggle bar that renders slotted arc-option elements as a row of mutually exclusive buttons with an active highlight.