tabs underline full-width even-spacing interactive tabs underline full-width even justified navigation full-width tab navigation evenly spaced underline tabs
Tabs Underline
Fetch pattern JSON:
curl https://webspire.de/patterns/tabs/underline.json underline.html
<div class="ws-tabs mx-auto max-w-3xl px-6 py-12">
<div role="tablist" aria-label="Content tabs" class="flex border-b border-[var(--ws-tabs-border)]">
<button role="tab" id="ul-tab-1" aria-selected="true" aria-controls="ul-panel-1" class="flex-1 border-b-2 border-[var(--ws-tabs-active-border)] py-3 text-center text-sm font-semibold text-[var(--ws-tabs-active-text)] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2" onclick="switchUnderlineTab(this, 'ul-panel-1')">Overview</button>
<button role="tab" id="ul-tab-2" aria-selected="false" aria-controls="ul-panel-2" class="flex-1 border-b-2 border-transparent py-3 text-center text-sm font-medium text-[var(--ws-tabs-text)] hover:border-[var(--ws-tabs-border)] hover:text-[var(--ws-tabs-active-text)] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2" onclick="switchUnderlineTab(this, 'ul-panel-2')">Features</button>
<button role="tab" id="ul-tab-3" aria-selected="false" aria-controls="ul-panel-3" class="flex-1 border-b-2 border-transparent py-3 text-center text-sm font-medium text-[var(--ws-tabs-text)] hover:border-[var(--ws-tabs-border)] hover:text-[var(--ws-tabs-active-text)] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2" onclick="switchUnderlineTab(this, 'ul-panel-3')">Pricing</button>
</div>
<div id="ul-panel-1" role="tabpanel" aria-labelledby="ul-tab-1" class="py-6">
<h3 class="text-lg font-semibold text-[var(--ws-tabs-active-text)]">Overview</h3>
<p class="mt-2 text-[var(--ws-tabs-text)]">This is the overview panel. It provides a high-level summary of the product, its purpose, and the value it delivers to users.</p>
</div>
<div id="ul-panel-2" role="tabpanel" aria-labelledby="ul-tab-2" class="hidden py-6">
<h3 class="text-lg font-semibold text-[var(--ws-tabs-active-text)]">Features</h3>
<p class="mt-2 text-[var(--ws-tabs-text)]">Explore the full feature set including responsive design, dark mode support, accessibility compliance, and copy-paste simplicity.</p>
</div>
<div id="ul-panel-3" role="tabpanel" aria-labelledby="ul-tab-3" class="hidden py-6">
<h3 class="text-lg font-semibold text-[var(--ws-tabs-active-text)]">Pricing</h3>
<p class="mt-2 text-[var(--ws-tabs-text)]">All patterns are free and open source. Use them in personal and commercial projects without any restrictions.</p>
</div>
<script>
function switchUnderlineTab(selectedTab, panelId) {
var tablist = selectedTab.closest('[role="tablist"]');
var container = tablist.parentElement;
tablist.querySelectorAll('[role="tab"]').forEach(function(tab) {
tab.setAttribute('aria-selected', 'false');
tab.className = 'flex-1 border-b-2 border-transparent py-3 text-center text-sm font-medium text-[var(--ws-tabs-text)] hover:border-[var(--ws-tabs-border)] hover:text-[var(--ws-tabs-active-text)] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2';
});
selectedTab.setAttribute('aria-selected', 'true');
selectedTab.className = 'flex-1 border-b-2 border-[var(--ws-tabs-active-border)] py-3 text-center text-sm font-semibold text-[var(--ws-tabs-active-text)] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2';
container.querySelectorAll('[role="tabpanel"]').forEach(function(panel) {
panel.classList.add('hidden');
});
container.querySelector('#' + panelId).classList.remove('hidden');
}
</script>
</div>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste Requires JS
Stable Published
tabsunderlinefull-widtheven-spacinginteractive
Slots
| Name | Required | Description |
|---|---|---|
| tabs | Yes | Full-width tab buttons with flex-1 for even spacing. |
| panels | Yes | Tab panels with role="tabpanel" and aria-labelledby. |
Full-width underline tabs where each button takes equal space via flex-1. Extends tabs/base with the same ARIA pattern but distributes tabs evenly across the container width.