Tab Slide
A copy-paste navigation component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.
NavigationHTMLCSSJavaScriptany framework
Copy into your project
HTML
<div class="nuda-tab-slide" role="tablist" aria-label="Content tabs">
<button class="nuda-tab-slide__tab active" role="tab" aria-selected="true">Overview</button>
<button class="nuda-tab-slide__tab" role="tab" aria-selected="false">Features</button>
<button class="nuda-tab-slide__tab" role="tab" aria-selected="false">Pricing</button>
<div class="nuda-tab-slide__indicator"></div>
</div>CSS
/* Tab Slide
Tabs with animated sliding indicator bar.
Customize: --tab-accent, --tab-text, --tab-border */
.nuda-tab-slide {
--tab-accent: #e4ff54;
--tab-text: #999;
--tab-border: rgba(255, 255, 255, 0.1);
display: flex;
position: relative;
border-bottom: 1px solid var(--tab-border);
}
.nuda-tab-slide__tab {
background: none;
border: none;
color: var(--tab-text);
font-size: 0.85rem;
padding: 0.75rem 1.25rem;
cursor: pointer;
transition: color 0.3s ease;
}
.nuda-tab-slide__tab:hover {
color: #fff;
}
.nuda-tab-slide__tab.active {
color: var(--tab-accent);
}
.nuda-tab-slide__indicator {
position: absolute;
bottom: -1px;
left: 0;
height: 2px;
background: var(--tab-accent);
border-radius: 2px;
transition: transform 0.3s ease, width 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
.nuda-tab-slide__indicator {
transition: none;
}
.nuda-tab-slide__tab {
transition: none;
}
}JavaScript
/* Tab Slide — Indicator positioning
Moves the indicator to align with the active tab. */
(function () {
const tablist = document.querySelector('.nuda-tab-slide');
if (!tablist) return;
const tabs = tablist.querySelectorAll('.nuda-tab-slide__tab');
const indicator = tablist.querySelector('.nuda-tab-slide__indicator');
if (!indicator) return;
function moveIndicator(tab) {
indicator.style.width = tab.offsetWidth + 'px';
indicator.style.transform = 'translateX(' + tab.offsetLeft + 'px)';
}
tabs.forEach(function (tab) {
tab.addEventListener('click', function () {
tabs.forEach(function (t) {
t.classList.remove('active');
t.setAttribute('aria-selected', 'false');
});
tab.classList.add('active');
tab.setAttribute('aria-selected', 'true');
moveIndicator(tab);
});
});
// Initialize indicator position
var active = tablist.querySelector('.nuda-tab-slide__tab.active');
if (active) moveIndicator(active);
})();How to use Tab Slide
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.