04 / 20
All 20 in 20 Tailwind CSS Responsive Navbars
- 01Tailwind Glassmorphism Frosted Navbar
- 02Tailwind Mega Menu Dropdown Navbar
- 03Tailwind Sidebar Drawer Navigation
- 04Tailwind Animated Underline Tabs Navbar
- 05Tailwind Pill Highlight Navigation Bar
- 06Tailwind Scroll-Aware Shrink Navbar
- 07Tailwind Neon Dark Navbar
- 08Tailwind Breadcrumb Reading Progress Navbar
- 09Tailwind Split Two-Tone Navbar
- 10Tailwind Bottom Tab Bar Navigation
- 11Tailwind Gradient Border Animated Navbar
- 12Tailwind Centered Logo Navbar
- 13Tailwind Icon Dot Indicator Navbar
- 14Tailwind Full-Screen Overlay Menu
- 15Tailwind Morphing Search Expand Navbar
- 16Tailwind Floating Island Multi-Segment Navbar
- 17Tailwind Step Progress Wizard Navbar
- 18Tailwind Vertical Rail Sidebar Navbar
- 19Tailwind Announcement Bar Dual Navbar
- 20Tailwind Scroll Spy Active Highlight Navbar
Tailwind Animated Underline Tabs Navbar
Docs-style tabs where the underline is an after: strip that scales from 0 to 0.6 on hover and to 1 on the current tab. All three states are utilities on the link, and the active one reads aria-current="page" — so the indicator and the screen-reader announcement come from the same attribute.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<div class="tnb-04 group w-full min-h-svh bg-tnb04-page font-tnb04-sans text-tnb04-ink" aria-label="Animated underline tabs navbar demo">
<input type="checkbox" id="tnb04-menu" class="sr-only peer" aria-label="Toggle navigation menu">
<header class="sticky top-0 z-100 border-b border-tnb04-track bg-tnb04-page">
<div class="flex h-15 items-center gap-6 px-5 md:px-10">
<a href="#home" class="shrink-0 text-xl font-extrabold tracking-[-0.04em] text-tnb04-ink no-underline">Stack<span class="text-tnb04-acc">.</span></a>
<div class="ml-auto hidden items-center gap-3 sm:flex">
<a href="#signin" class="text-sm font-semibold text-tnb04-mut no-underline transition-colors hover:text-tnb04-ink">Sign in</a>
<a href="#build" class="rounded-md bg-tnb04-ink px-4 py-2 text-sm font-bold tracking-[-0.01em] text-white no-underline transition-[background,translate] duration-200 hover:-translate-y-px hover:bg-tnb04-acc motion-reduce:transition-none motion-reduce:hover:translate-y-0">Start building</a>
</div>
<label for="tnb04-menu" class="ml-auto flex size-11 cursor-pointer flex-col items-center justify-center gap-1.5 sm:hidden" aria-hidden="true">
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:translate-y-2 group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-opacity duration-300 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:-translate-y-2 group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
</div>
<nav class="hidden h-12 items-end overflow-x-auto px-5 [scrollbar-width:none] sm:flex md:px-10" aria-label="Sections">
<a href="#overview" aria-current="page" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc aria-[current=page]:text-tnb04-acc aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none">Overview</a>
<a href="#components" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Components <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">48</span></a>
<a href="#templates" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Templates <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">12</span></a>
<a href="#docs" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Documentation</a>
<a href="#changelog" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Changelog <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">3</span></a>
<a href="#community" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Community</a>
<a href="#showcase" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Showcase</a>
</nav>
<div class="hidden border-t border-tnb04-track px-5 py-2 max-sm:group-has-checked:grid">
<a href="#overview" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-acc no-underline">Overview</a>
<a href="#components" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Components</a>
<a href="#templates" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Templates</a>
<a href="#docs" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Documentation</a>
<a href="#changelog" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Changelog</a>
<a href="#build" class="mt-2 flex min-h-11 items-center justify-center rounded-md bg-tnb04-ink text-sm font-bold text-white no-underline">Start building</a>
</div>
</header>
<main class="mx-auto max-w-3xl px-5 py-16 md:px-10">
<h1 class="mb-4 text-4xl font-extrabold tracking-[-0.04em] text-tnb04-ink">Animated Underline <span class="text-tnb04-acc">Tabs</span></h1>
<p class="text-lg leading-relaxed text-tnb04-mut">Hover any tab for the 60% tease; the current tab holds 100%. Both are <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">after:scale-x-*</code> values on the link — and the active state is <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">aria-current</code>, not a class.</p>
</main>
</div><div class="tnb-04 group w-full min-h-svh bg-tnb04-page font-tnb04-sans text-tnb04-ink" aria-label="Animated underline tabs navbar demo">
<input type="checkbox" id="tnb04-menu" class="sr-only peer" aria-label="Toggle navigation menu">
<header class="sticky top-0 z-100 border-b border-tnb04-track bg-tnb04-page">
<div class="flex h-15 items-center gap-6 px-5 md:px-10">
<a href="#home" class="shrink-0 text-xl font-extrabold tracking-[-0.04em] text-tnb04-ink no-underline">Stack<span class="text-tnb04-acc">.</span></a>
<div class="ml-auto hidden items-center gap-3 sm:flex">
<a href="#signin" class="text-sm font-semibold text-tnb04-mut no-underline transition-colors hover:text-tnb04-ink">Sign in</a>
<a href="#build" class="rounded-md bg-tnb04-ink px-4 py-2 text-sm font-bold tracking-[-0.01em] text-white no-underline transition-[background,translate] duration-200 hover:-translate-y-px hover:bg-tnb04-acc motion-reduce:transition-none motion-reduce:hover:translate-y-0">Start building</a>
</div>
<label for="tnb04-menu" class="ml-auto flex size-11 cursor-pointer flex-col items-center justify-center gap-1.5 sm:hidden" aria-hidden="true">
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:translate-y-2 group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-opacity duration-300 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:-translate-y-2 group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
</div>
<nav class="hidden h-12 items-end overflow-x-auto px-5 [scrollbar-width:none] sm:flex md:px-10" aria-label="Sections">
<a href="#overview" aria-current="page" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc aria-[current=page]:text-tnb04-acc aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none">Overview</a>
<a href="#components" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Components <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">48</span></a>
<a href="#templates" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Templates <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">12</span></a>
<a href="#docs" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Documentation</a>
<a href="#changelog" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Changelog <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">3</span></a>
<a href="#community" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Community</a>
<a href="#showcase" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Showcase</a>
</nav>
<div class="hidden border-t border-tnb04-track px-5 py-2 max-sm:group-has-checked:grid">
<a href="#overview" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-acc no-underline">Overview</a>
<a href="#components" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Components</a>
<a href="#templates" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Templates</a>
<a href="#docs" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Documentation</a>
<a href="#changelog" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Changelog</a>
<a href="#build" class="mt-2 flex min-h-11 items-center justify-center rounded-md bg-tnb04-ink text-sm font-bold text-white no-underline">Start building</a>
</div>
</header>
<main class="mx-auto max-w-3xl px-5 py-16 md:px-10">
<h1 class="mb-4 text-4xl font-extrabold tracking-[-0.04em] text-tnb04-ink">Animated Underline <span class="text-tnb04-acc">Tabs</span></h1>
<p class="text-lg leading-relaxed text-tnb04-mut">Hover any tab for the 60% tease; the current tab holds 100%. Both are <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">after:scale-x-*</code> values on the link — and the active state is <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">aria-current</code>, not a class.</p>
</main>
</div>@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The
.tab::after/.tab:hover::after/.tab.is-active::aftertrio becomes three utilities on the link, in reading order: rest, hover, current. .is-activeis gone entirely —aria-current="page"drives colour, underline and badge tint, so the visual and the announcement cannot disagree.scrollbar-width:noneships as an arbitrary property; the::-webkit-scrollbarhalf stays in CSS because Tailwind has no variant for vendor pseudo-elements.- The mobile list replaces a second full tab row, which the CSS version had to keep in sync by hand.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Animated Underline Tabs Navbar
Source: https://codefronts.com/navigation/tailwind-css-responsive-navbars/tailwind-animated-underline-tabs-navbar/
Docs-style tabs where the underline is an after: strip that scales from 0 to 0.6 on hover and to 1 on the current tab. All three states are utilities on the link, and the active one reads aria-current="page" — so the indicator and the screen-reader announcement come from the same attribute.
## HTML
```html
<div class="tnb-04 group w-full min-h-svh bg-tnb04-page font-tnb04-sans text-tnb04-ink" aria-label="Animated underline tabs navbar demo">
<input type="checkbox" id="tnb04-menu" class="sr-only peer" aria-label="Toggle navigation menu">
<header class="sticky top-0 z-100 border-b border-tnb04-track bg-tnb04-page">
<div class="flex h-15 items-center gap-6 px-5 md:px-10">
<a href="#home" class="shrink-0 text-xl font-extrabold tracking-[-0.04em] text-tnb04-ink no-underline">Stack<span class="text-tnb04-acc">.</span></a>
<div class="ml-auto hidden items-center gap-3 sm:flex">
<a href="#signin" class="text-sm font-semibold text-tnb04-mut no-underline transition-colors hover:text-tnb04-ink">Sign in</a>
<a href="#build" class="rounded-md bg-tnb04-ink px-4 py-2 text-sm font-bold tracking-[-0.01em] text-white no-underline transition-[background,translate] duration-200 hover:-translate-y-px hover:bg-tnb04-acc motion-reduce:transition-none motion-reduce:hover:translate-y-0">Start building</a>
</div>
<label for="tnb04-menu" class="ml-auto flex size-11 cursor-pointer flex-col items-center justify-center gap-1.5 sm:hidden" aria-hidden="true">
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:translate-y-2 group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-opacity duration-300 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:-translate-y-2 group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
</div>
<nav class="hidden h-12 items-end overflow-x-auto px-5 [scrollbar-width:none] sm:flex md:px-10" aria-label="Sections">
<a href="#overview" aria-current="page" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc aria-[current=page]:text-tnb04-acc aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none">Overview</a>
<a href="#components" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Components <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">48</span></a>
<a href="#templates" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Templates <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">12</span></a>
<a href="#docs" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Documentation</a>
<a href="#changelog" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Changelog <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">3</span></a>
<a href="#community" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Community</a>
<a href="#showcase" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Showcase</a>
</nav>
<div class="hidden border-t border-tnb04-track px-5 py-2 max-sm:group-has-checked:grid">
<a href="#overview" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-acc no-underline">Overview</a>
<a href="#components" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Components</a>
<a href="#templates" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Templates</a>
<a href="#docs" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Documentation</a>
<a href="#changelog" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Changelog</a>
<a href="#build" class="mt-2 flex min-h-11 items-center justify-center rounded-md bg-tnb04-ink text-sm font-bold text-white no-underline">Start building</a>
</div>
</header>
<main class="mx-auto max-w-3xl px-5 py-16 md:px-10">
<h1 class="mb-4 text-4xl font-extrabold tracking-[-0.04em] text-tnb04-ink">Animated Underline <span class="text-tnb04-acc">Tabs</span></h1>
<p class="text-lg leading-relaxed text-tnb04-mut">Hover any tab for the 60% tease; the current tab holds 100%. Both are <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">after:scale-x-*</code> values on the link — and the active state is <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">aria-current</code>, not a class.</p>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Animated Underline Tabs Navbar
Source: https://codefronts.com/navigation/tailwind-css-responsive-navbars/tailwind-animated-underline-tabs-navbar/
Docs-style tabs where the underline is an after: strip that scales from 0 to 0.6 on hover and to 1 on the current tab. All three states are utilities on the link, and the active one reads aria-current="page" — so the indicator and the screen-reader announcement come from the same attribute.
## HTML
```html
<div class="tnb-04 group w-full min-h-svh bg-tnb04-page font-tnb04-sans text-tnb04-ink" aria-label="Animated underline tabs navbar demo">
<input type="checkbox" id="tnb04-menu" class="sr-only peer" aria-label="Toggle navigation menu">
<header class="sticky top-0 z-100 border-b border-tnb04-track bg-tnb04-page">
<div class="flex h-15 items-center gap-6 px-5 md:px-10">
<a href="#home" class="shrink-0 text-xl font-extrabold tracking-[-0.04em] text-tnb04-ink no-underline">Stack<span class="text-tnb04-acc">.</span></a>
<div class="ml-auto hidden items-center gap-3 sm:flex">
<a href="#signin" class="text-sm font-semibold text-tnb04-mut no-underline transition-colors hover:text-tnb04-ink">Sign in</a>
<a href="#build" class="rounded-md bg-tnb04-ink px-4 py-2 text-sm font-bold tracking-[-0.01em] text-white no-underline transition-[background,translate] duration-200 hover:-translate-y-px hover:bg-tnb04-acc motion-reduce:transition-none motion-reduce:hover:translate-y-0">Start building</a>
</div>
<label for="tnb04-menu" class="ml-auto flex size-11 cursor-pointer flex-col items-center justify-center gap-1.5 sm:hidden" aria-hidden="true">
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:translate-y-2 group-has-checked:rotate-45 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-opacity duration-300 group-has-checked:opacity-0 motion-reduce:transition-none"></span>
<span class="block h-0.5 w-5.5 rounded-sm bg-tnb04-ink transition-transform duration-300 group-has-checked:-translate-y-2 group-has-checked:-rotate-45 motion-reduce:transition-none"></span>
</label>
</div>
<nav class="hidden h-12 items-end overflow-x-auto px-5 [scrollbar-width:none] sm:flex md:px-10" aria-label="Sections">
<a href="#overview" aria-current="page" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc aria-[current=page]:text-tnb04-acc aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none">Overview</a>
<a href="#components" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Components <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">48</span></a>
<a href="#templates" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Templates <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">12</span></a>
<a href="#docs" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Documentation</a>
<a href="#changelog" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Changelog <span class="min-w-5 rounded-full bg-tnb04-track px-1.5 text-center text-[11px] font-bold text-tnb04-mut">3</span></a>
<a href="#community" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Community</a>
<a href="#showcase" class="relative inline-flex h-full shrink-0 items-center gap-1.5 px-5 text-sm font-semibold whitespace-nowrap text-tnb04-mut no-underline transition-colors duration-200 after:absolute after:inset-x-5 after:bottom-0 after:h-[2.5px] after:origin-center after:scale-x-0 after:rounded-t-sm after:bg-tnb04-acc after:transition-transform after:duration-250 hover:text-tnb04-ink hover:after:scale-x-60 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tnb04-acc motion-reduce:after:transition-none">Showcase</a>
</nav>
<div class="hidden border-t border-tnb04-track px-5 py-2 max-sm:group-has-checked:grid">
<a href="#overview" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-acc no-underline">Overview</a>
<a href="#components" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Components</a>
<a href="#templates" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Templates</a>
<a href="#docs" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Documentation</a>
<a href="#changelog" class="flex min-h-11 items-center rounded-md px-2 text-[15px] font-semibold text-tnb04-ink no-underline transition-colors hover:bg-tnb04-tint hover:text-tnb04-acc">Changelog</a>
<a href="#build" class="mt-2 flex min-h-11 items-center justify-center rounded-md bg-tnb04-ink text-sm font-bold text-white no-underline">Start building</a>
</div>
</header>
<main class="mx-auto max-w-3xl px-5 py-16 md:px-10">
<h1 class="mb-4 text-4xl font-extrabold tracking-[-0.04em] text-tnb04-ink">Animated Underline <span class="text-tnb04-acc">Tabs</span></h1>
<p class="text-lg leading-relaxed text-tnb04-mut">Hover any tab for the 60% tease; the current tab holds 100%. Both are <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">after:scale-x-*</code> values on the link — and the active state is <code class="rounded bg-tnb04-tint px-1.5 py-0.5 text-[0.9em] text-tnb04-acc">aria-current</code>, not a class.</p>
</main>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tnb04-page: #ffffff;
--color-tnb04-page: oklch(1 0 0);
--color-tnb04-ink: #1c1c1c;
--color-tnb04-ink: oklch(0.24 0 0);
--color-tnb04-mut: #6f6f6f;
--color-tnb04-mut: oklch(0.54 0 0);
--color-tnb04-track: #f0ebe3;
--color-tnb04-track: oklch(0.94 0.01 80);
--color-tnb04-tint: #ffe8df;
--color-tnb04-tint: oklch(0.94 0.03 40);
--color-tnb04-acc: #ff6b35;
--color-tnb04-acc: oklch(0.68 0.2 40);
--font-tnb04-sans: 'Manrope', system-ui, sans-serif;
}
.tnb-04 {
width: 100%;
min-height: 100svh;
}
.tnb-04 ::selection {
background: var(--color-tnb04-acc);
color: #fff;
}
/* Scrollbar hiding needs a vendor pseudo-element: no variant form exists. */
.tnb-04 nav::-webkit-scrollbar {
display: none;
}
```How this works
Scale, not width. Animating width on a pseudo-element reflows; scaleX runs on the compositor. The strip is full width at rest and simply squashed to zero:
class="after:absolute after:inset-x-0 after:bottom-0 after:h-0.5
after:origin-left after:scale-x-0 after:bg-tnb04-acc
hover:after:scale-x-60 aria-[current=page]:after:scale-x-100"The hover preview is a value, not a second rule. scale-x-60 is the 60% tease the CSS original wrote as a separate :hover::after block.
The row scrolls rather than wraps, with the scrollbar hidden — a seven-tab docs header on a phone is a horizontal scroller, and pretending otherwise produces a two-line bar that jumps.
Make it yours
- Thickness:
after:h-0.5→after:h-1for a bolder rule. - Top indicator: swap
after:bottom-0forafter:top-0. - Centre growth: drop
origin-left— the default origin is the centre, which reads as a spread rather than a wipe. - Counts: the badge is
bg-tnb04-track, tinted tobg-tnb04-tinton the current tab via the samearia-[current=page]:hook.
Gotchas — read before shipping
- The strip needs
relativeon the link, orafter:absoluteresolves against the nearest positioned ancestor and spans the whole bar. scale-x-60is a hover tease — do not also transitionopacity, or the two curves fight and the underline appears to stutter.- Hiding the scrollbar removes the only visual cue that the row scrolls; keep the overflowing tab partially visible so the affordance survives.
aria-currenttakes the valuepagefor navigation, nottrue—aria-[current=page]:matches exactly that.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
scrollbar-width is Baseline 2024; the ::-webkit-scrollbar shim covers older Safari.