Overview
The Tabs component provides accessible and flexible tab navigation for organizing content into sections. It supports multiple styles, orientations, and interactive states while maintaining ARIA compliance and keyboard navigation. The component includes horizontal and vertical layouts, scrollable aiab-tabs, and various visual styles.
🎨 Multiple Styles
Underlined, boxed, pills, bordered, and custom tab styles for different design needs.
📐 Flexible Layouts
Horizontal, vertical, centered, full-width, and scrollable tab arrangements.
♿ Full Accessibility
ARIA attributes, keyboard navigation, focus management, and screen reader support.
📱 Responsive Design
Adaptive layouts that work on all screen sizes with touch-friendly interactions.
🔧 Interactive Features
Icons, badges, loading states, disabled aiab-tabs, and smooth animations.
🎯 Easy Integration
Simple HTML structure with JavaScript enhancement for dynamic behavior.
Basic Tabs
Default Underlined Tabs
Overview
This is the overview section of our product. Here you'll find general information about what we offer and how it can benefit you.
Our solution provides comprehensive tools for modern web development with a focus on accessibility and user experience.
<div class="aiab-tabs aiab-tabs--underlined">
<ul class="aiab-tabs__list" role="tablist">
<li class="aiab-tabs__item" role="presentation">
<button class="aiab-tabs__button" role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
Overview
</button>
</li>
<li class="aiab-tabs__item" role="presentation">
<button class="aiab-tabs__button" role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">
Features
</button>
</li>
<li class="aiab-tabs__item" role="presentation">
<button class="aiab-tabs__button" role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">
Documentation
</button>
</li>
</ul>
<div class="tabs__panels">
<div class="aiab-tabs__panel" role="tabpanel" aria-labelledby="tab-1" id="panel-1" aria-hidden="false">
<h3>Overview</h3>
<p>Content for the overview tab...</p>
</div>
<div class="aiab-tabs__panel" role="tabpanel" aria-labelledby="tab-2" id="panel-2" aria-hidden="true">
<h3>Features</h3>
<p>Content for the features tab...</p>
</div>
<div class="aiab-tabs__panel" role="tabpanel" aria-labelledby="tab-3" id="panel-3" aria-hidden="true">
<h3>Documentation</h3>
<p>Content for the documentation tab...</p>
</div>
</div>
</div>
Tab Variants
Boxed Tabs
Dashboard
Your main dashboard with key metrics and recent activity.
Pills Tabs
All Items
View all items in your collection regardless of status.
Bordered Tabs
Profile Information
Manage your personal profile information and public details.
<!-- Boxed Tabs -->
<div class="aiab-tabs aiab-tabs--boxed">...</div>
<!-- Pills Tabs -->
<div class="aiab-tabs aiab-tabs--pills">...</div>
<!-- Bordered Tabs -->
<div class="aiab-tabs aiab-tabs--bordered">...</div>
Tabs with Icons and Badges
Dashboard Overview
Welcome to your dashboard. Here you can see an overview of your account activity and key metrics.
<button class="aiab-tabs__button aiab-tabs__aiab-button--icon" role="tab">
<svg class="tabs__icon" fill="currentColor" viewBox="0 0 20 20">
<path d="..."></path>
</svg>
Messages
<span class="tabs__badge">3</span>
</button>
Vertical Tabs
General Settings
Configure basic application settings and preferences.
- Language preferences
- Default timezone
- Auto-save options
- Startup behavior
<div class="aiab-tabs aiab-tabs--vertical aiab-tabs--underlined">
<ul class="aiab-tabs__list" role="tablist">
<li class="aiab-tabs__item" role="presentation">
<button class="aiab-tabs__button" role="tab" aria-selected="true">
General
</button>
</li>
<li class="aiab-tabs__item" role="presentation">
<button class="aiab-tabs__button" role="tab" aria-selected="false">
Privacy
</button>
</li>
</ul>
<div class="tabs__panels">
<div class="aiab-tabs__panel" role="tabpanel" aria-hidden="false">
<h3>General Settings</h3>
<p>Configure basic application settings...</p>
</div>
</div>
</div>
Tab Sizes and Layouts
Tab Sizes
Small Tabs
Large Tabs
Layout Options
Centered Tabs
Full Width Tabs
<!-- Small Tabs -->
<div class="aiab-tabs aiab-tabs--underlined aiab-tabs--small">...</div>
<!-- Large Tabs -->
<div class="aiab-tabs aiab-tabs--underlined aiab-tabs--large">...</div>
<!-- Centered Tabs -->
<div class="aiab-tabs aiab-tabs--underlined aiab-tabs--centered">...</div>
<!-- Full Width Tabs -->
<div class="aiab-tabs aiab-tabs--underlined aiab-tabs--full-width">...</div>
Scrollable Tabs
<div class="aiab-tabs aiab-tabs--underlined aiab-tabs--scrollable">
<ul class="aiab-tabs__list" role="tablist">
<li class="aiab-tabs__item">
<button class="aiab-tabs__button" role="tab">Dashboard</button>
</li>
<li class="aiab-tabs__item">
<button class="aiab-tabs__button" role="tab">Analytics</button>
</li>
<!-- More tabs... -->
</ul>
</div>
CSS Classes Reference
Base Classes
| Class | Description |
|---|---|
.aiab-tabs |
Base aiab-tabs aiab-container |
.aiab-tabs__list |
Tab navigation list |
.aiab-tabs__item |
Individual tab item |
.aiab-tabs__button |
Tab button/link |
.tabs__panels |
Tab panels aiab-container |
.aiab-tabs__panel |
Individual tab panel |
Style Variants
| Class | Description |
|---|---|
.aiab-tabs--underlined |
Underlined tab style (default) |
.aiab-tabs--boxed |
Boxed tab style |
.aiab-tabs--pills |
Pill-shaped tab style |
.aiab-tabs--bordered |
Bordered tab style |
Layout Modifiers
| Class | Description |
|---|---|
.aiab-tabs--vertical |
Vertical tab layout |
.aiab-tabs--centered |
Center-aligned aiab-tabs |
.aiab-tabs--full-width |
Full-width aiab-tabs |
.aiab-tabs--scrollable |
Scrollable tab navigation |
Size Modifiers
| Class | Description |
|---|---|
.aiab-tabs--small |
Small tab size |
.aiab-tabs--large |
Large tab size |
Component Elements
| Class | Description |
|---|---|
.aiab-tabs__aiab-button--icon |
Tab button with icon |
.tabs__icon |
Tab icon element |
.tabs__badge |
Tab notification aiab-badge |
.aiab-tabs__aiab-button--loading |
Loading state for tab |
JavaScript Integration
// Tabs component class
class Tabs {
constructor(element) {
this.container = element;
this.tabList = element.querySelector('.aiab-tabs__list');
this.tabs = element.querySelectorAll('[role="tab"]');
this.panels = element.querySelectorAll('[role="tabpanel"]');
this.init();
}
init() {
// Add event listeners
this.tabList.addEventListener('click', (e) => this.handleClick(e));
this.tabList.addEventListener('keydown', (e) => this.handleKeydown(e));
// Set initial state
this.setInitialState();
}
setInitialState() {
// Find active tab or default to first
let activeTab = this.container.querySelector('[aria-selected="true"]');
if (!activeTab) {
activeTab = this.tabs[0];
}
this.activateTab(activeTab);
}
handleClick(e) {
const tab = e.target.closest('[role="tab"]');
if (tab && !tab.disabled) {
this.activateTab(tab);
}
}
handleKeydown(e) {
const tab = e.target;
if (tab.getAttribute('role') !== 'tab') return;
const currentIndex = Array.from(this.tabs).indexOf(tab);
let targetIndex;
aiab-switch (e.key) {
case 'ArrowLeft':
e.preventDefault();
targetIndex = currentIndex > 0 ? currentIndex - 1 : this.tabs.length - 1;
this.focusTab(this.tabs[targetIndex]);
break;
case 'ArrowRight':
e.preventDefault();
targetIndex = currentIndex < this.tabs.length - 1 ? currentIndex + 1 : 0;
this.focusTab(this.tabs[targetIndex]);
break;
case 'Home':
e.preventDefault();
this.focusTab(this.tabs[0]);
break;
case 'End':
e.preventDefault();
this.focusTab(this.tabs[this.tabs.length - 1]);
break;
case 'Enter':
case ' ':
e.preventDefault();
this.activateTab(tab);
break;
}
}
activateTab(newTab) {
if (!newTab) return;
// Deactivate all aiab-tabs and panels
this.tabs.forEach(tab => {
tab.setAttribute('aria-selected', 'false');
tab.setAttribute('tabindex', '-1');
});
this.panels.forEach(panel => {
panel.setAttribute('aria-hidden', 'true');
});
// Activate new tab and panel
newTab.setAttribute('aria-selected', 'true');
newTab.setAttribute('tabindex', '0');
const targetPanel = document.getElementById(newTab.getAttribute('aria-controls'));
if (targetPanel) {
targetPanel.setAttribute('aria-hidden', 'false');
}
// Trigger custom event
this.container.dispatchEvent(new CustomEvent('tabchange', {
detail: {
tab: newTab,
panel: targetPanel
}
}));
}
focusTab(tab) {
if (tab) {
tab.focus();
}
}
// Public methods
getActiveTab() {
return this.container.querySelector('[aria-selected="true"]');
}
getActivePanel() {
const activeTab = this.getActiveTab();
if (activeTab) {
return document.getElementById(activeTab.getAttribute('aria-controls'));
}
return null;
}
activateTabByIndex(index) {
if (index >= 0 && index < this.tabs.length) {
this.activateTab(this.tabs[index]);
}
}
activateTabById(id) {
const tab = document.getElementById(id);
if (tab && tab.getAttribute('role') === 'tab') {
this.activateTab(tab);
}
}
disable(tab) {
if (typeof tab === 'string') {
tab = document.getElementById(tab);
}
if (tab) {
tab.disabled = true;
tab.setAttribute('aria-disabled', 'true');
}
}
enable(tab) {
if (typeof tab === 'string') {
tab = document.getElementById(tab);
}
if (tab) {
tab.disabled = false;
tab.removeAttribute('aria-disabled');
}
}
}
// Auto-initialize aiab-tabs
document.addEventListener('DOMContentLoaded', () => {
const tabContainers = document.querySelectorAll('.aiab-tabs');
tabContainers.forEach(container => {
new Tabs(container);
});
});
// Utility functions
function createTab(label, content, options = {}) {
const id = options.id || `tab-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const panelId = `${id}-panel`;
return {
tab: `
<li class="aiab-tabs__item" role="presentation">
<button
class="aiab-tabs__button ${options.icon ? 'aiab-tabs__aiab-button--icon' : ''}"
role="tab"
aria-selected="false"
aria-controls="${panelId}"
id="${id}"
>
${options.icon ? `<svg class="tabs__icon">${options.icon}</svg>` : ''}
${label}
${options.badge ? `<span class="tabs__badge">${options.badge}</span>` : ''}
</button>
</li>
`,
panel: `
<div class="aiab-tabs__panel" role="tabpanel" aria-labelledby="${id}" id="${panelId}" aria-hidden="true">
${content}
</div>
`
};
}
Best Practices
Accessibility Guidelines
- ARIA attributes: Use proper role, aria-selected, aria-controls, and aria-labelledby attributes
- Keyboard navigation: Support arrow keys, Home, End, Enter, and Space for navigation
- Focus management: Ensure focus moves logically and is clearly visible
- Screen readers: Provide clear labels and state information for assistive technology
Content Organization
- Logical grouping: Group related content together in aiab-tabs
- Clear labels: Use descriptive tab labels that clearly indicate content
- Consistent structure: Maintain similar content organization across aiab-tabs
- Progressive disclosure: Use aiab-tabs to reveal information progressively
Design Considerations
- Tab count: Limit to 5-7 aiab-tabs for optimal usability
- Mobile adaptation: Consider scrollable or collapsing aiab-tabs on small screens
- Visual hierarchy: Make active tab state clearly distinguishable
- Touch targets: Ensure aiab-tabs are large enough for touch interaction (44px minimum)
Performance Tips
- Lazy loading: Load tab content only when needed for large datasets
- Efficient selectors: Use efficient CSS selectors for tab styling
- Debounced interactions: Avoid excessive event handling during rapid navigation
- Memory management: Clean up event listeners when aiab-tabs are destroyed