Tabs
Introduction
The Tabs component provides a way to organize content into different sections that can be accessed one at a time. It follows WAI-ARIA guidelines and includes full keyboard support and proper ARIA attributes.
When to use
Use the Tabs component when you need to:
- Organize related content into sections
- Switch between different views
- Present form sections
- Display product details
- Show settings panels
- Structure dashboard sections
Usage
The Tabs component consists of four parts: the container, list wrapper, individual tabs, and their corresponding panels.
---import { Tabs, TabsList, TabsTab, TabsPanel } from 'accessible-astro-components'---
<Tabs> <TabsList> <TabsTab id="tab1" controls="panel1" selected>First tab</TabsTab> <TabsTab id="tab2" controls="panel2">Second tab</TabsTab> <TabsTab id="tab3" controls="panel3">Third tab</TabsTab> </TabsList>
<TabsPanel id="panel1" labelledby="tab1" selected> <h2>First panel</h2> <p>Content for first panel</p> </TabsPanel> <TabsPanel id="panel2" labelledby="tab2"> <h2>Second panel</h2> <p>Content for second panel</p> </TabsPanel> <TabsPanel id="panel3" labelledby="tab3"> <h2>Third panel</h2> <p>Content for third panel</p> </TabsPanel></Tabs>
Props
Each component in the Tabs system accepts specific props:
Tabs
Prop | Type | Default | Description |
---|---|---|---|
class | string | '' | Additional CSS classes to apply |
TabsList
Prop | Type | Default | Description |
---|---|---|---|
class | string | '' | Additional CSS classes to apply |
TabsTab
Prop | Type | Default | Description |
---|---|---|---|
id | string | Required | Unique identifier for the tab |
controls | string | Required | ID of the panel this tab controls |
selected | boolean | false | Whether this tab is initially selected |
class | string | '' | Additional CSS classes to apply |
TabsPanel
Prop | Type | Default | Description |
---|---|---|---|
id | string | Required | Unique identifier for the panel |
labelledby | string | Required | ID of the tab that labels this panel |
selected | boolean | false | Whether this panel is initially visible |
class | string | '' | Additional CSS classes to apply |
Accessibility
Accessibility isn’t an afterthought - it’s built into the core of this component through semantic HTML elements and proper ARIA attributes. The Tabs component is built with accessibility in mind:
- Proper ARIA roles (
tablist
,tab
,tabpanel
) - Keyboard navigation:
- Left/Right arrows to move between tabs
- Tab/Shift+Tab for focus management
- Clear focus indicators
- Proper ARIA states (
aria-selected
,aria-controls
,aria-labelledby
) - Semantic HTML structure
- Proper focus management
- Smooth transitions (respecting reduced-motion preferences)
Styling
Make the Tabs component your own while maintaining its accessibility features.
/* Option 1: Using :global() in your style block */<style> :global(.tab) { flex-grow: 1; padding-block: 0.75rem; padding-inline: 1rem; border: 2px solid; border-radius: 0.5rem; border-color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%)); background-color: transparent; color: inherit; font-weight: 700; cursor: pointer; }
:global(.tab[aria-selected='true']), :global(.tab:hover), :global(.tab:focus-visible) { color: light-dark(hsl(0 0% 100%), hsl(215 25% 27%)); background-color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%)); }
:global(.tab-panel) { display: flex; flex-direction: column; min-block-size: 10rem; padding: 2rem; border: 2px solid; border-color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%)); border-end-end-radius: 0.5rem; border-end-start-radius: 0.5rem; }</style>
/* Option 2: Using is:global on the style tag */<style is:global> .tab { /* Same as above */ }
.tab[aria-selected='true'], .tab:hover, .tab:focus-visible { /* Same as above */ }
.tab-panel { /* Same as above */ }</style>
<Tabs class="w-full"> <TabsList class="flex gap-2"> <TabsTab class="flex-1 px-4 py-2 font-bold rounded-t border-2 hover:bg-gray-100 dark:hover:bg-gray-800" id="tab1" controls="panel1" selected > Tab 1 </TabsTab> </TabsList> <TabsPanel class="p-4 border-2 rounded-b min-h-[10rem]" id="panel1" labelledby="tab1" selected > Panel content </TabsPanel></Tabs>
Interactive example
First panel
Try using the arrow keys to navigate between tabs!