Component

Tabs

Complete tab component family with 15 production-ready variants covering documentation, dashboards, settings, mobile navigation, and animated indicators.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.site/library/tailwind/components/tabs/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Tabs
registry path: Tailwind/Components/Tabs

Source

Implementation

code.html
<div class="w-full max-w-3xl">
  <div class="relative">
    <div role="tablist" aria-label="Project workspace" class="flex items-center gap-6 border-b border-gray-200">
      <button role="tab" id="atab-board" aria-selected="true" aria-controls="apanel-board" tabindex="0"
        class="relative pb-3 text-sm font-medium text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 rounded whitespace-nowrap">
        Board
      </button>
      <button role="tab" id="atab-timeline" aria-selected="false" aria-controls="apanel-timeline" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 rounded whitespace-nowrap">
        Timeline
      </button>
      <button role="tab" id="atab-calendar" aria-selected="false" aria-controls="apanel-calendar" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 rounded whitespace-nowrap">
        Calendar
      </button>
      <button role="tab" id="atab-files" aria-selected="false" aria-controls="apanel-files" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 rounded whitespace-nowrap">
        Files
      </button>
      <span class="a-indicator absolute bottom-0 h-0.5 bg-rose-500 rounded-full transition-all duration-300 ease-out" aria-hidden="true"></span>
    </div>
  </div>

  <div class="mt-6">
    <div role="tabpanel" id="apanel-board" aria-labelledby="atab-board" tabindex="0" class="grid grid-cols-3 gap-3 focus:outline-none">
      <div class="rounded-xl bg-gray-50 border border-gray-200 p-3"><p class="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">To do</p><div class="rounded-lg bg-white border border-gray-200 p-3"><p class="text-sm font-medium text-gray-900">Design review</p><p class="text-xs text-gray-500 mt-1">Due Aug 6</p></div></div>
      <div class="rounded-xl bg-gray-50 border border-gray-200 p-3"><p class="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">In progress</p><div class="rounded-lg bg-white border border-gray-200 p-3"><p class="text-sm font-medium text-gray-900">API integration</p><p class="text-xs text-gray-500 mt-1">Due Aug 8</p></div></div>
      <div class="rounded-xl bg-gray-50 border border-gray-200 p-3"><p class="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2">Done</p><div class="rounded-lg bg-white border border-gray-200 p-3"><p class="text-sm font-medium text-gray-900">User research</p><p class="text-xs text-emerald-600 mt-1">Completed</p></div></div>
    </div>
    <div role="tabpanel" id="apanel-timeline" aria-labelledby="atab-timeline" tabindex="0" class="hidden focus:outline-none">
      <ol class="relative border-l border-gray-200 ml-3 space-y-5">
        <li class="ml-4"><span class="absolute -left-[5px] w-2.5 h-2.5 bg-rose-500 rounded-full"></span><p class="text-sm font-medium text-gray-900">Project kickoff</p><p class="text-xs text-gray-500">Aug 1</p></li>
        <li class="ml-4"><span class="absolute -left-[5px] w-2.5 h-2.5 bg-gray-300 rounded-full"></span><p class="text-sm font-medium text-gray-900">Design sprint</p><p class="text-xs text-gray-500">Aug 3 — Aug 5</p></li>
        <li class="ml-4"><span class="absolute -left-[5px] w-2.5 h-2.5 bg-gray-300 rounded-full"></span><p class="text-sm font-medium text-gray-900">Launch</p><p class="text-xs text-gray-500">Aug 15</p></li>
      </ol>
    </div>
    <div role="tabpanel" id="apanel-calendar" aria-labelledby="atab-calendar" tabindex="0" class="hidden focus:outline-none">
      <div class="grid grid-cols-7 gap-1 text-center text-xs">
        <div class="text-gray-400 font-medium py-1">M</div><div class="text-gray-400 font-medium py-1">T</div><div class="text-gray-400 font-medium py-1">W</div><div class="text-gray-400 font-medium py-1">T</div><div class="text-gray-400 font-medium py-1">F</div><div class="text-gray-400 font-medium py-1">S</div><div class="text-gray-400 font-medium py-1">S</div>
        <div class="py-2 rounded bg-rose-50 text-rose-700 font-semibold">4</div><div class="py-2 rounded hover:bg-gray-100">5</div><div class="py-2 rounded hover:bg-gray-100">6</div><div class="py-2 rounded hover:bg-gray-100">7</div><div class="py-2 rounded hover:bg-gray-100">8</div><div class="py-2 rounded hover:bg-gray-100">9</div><div class="py-2 rounded hover:bg-gray-100">10</div>
      </div>
    </div>
    <div role="tabpanel" id="apanel-files" aria-labelledby="atab-files" tabindex="0" class="hidden focus:outline-none">
      <div class="divide-y divide-gray-100 rounded-xl border border-gray-200">
        <div class="flex items-center gap-3 p-3"><span class="w-8 h-8 rounded-lg bg-rose-50 text-rose-600 flex items-center justify-center"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg></span><div class="min-w-0 flex-1"><p class="text-sm font-medium text-gray-900 truncate">spec-v2.pdf</p><p class="text-xs text-gray-500">2.4 MB</p></div></div>
        <div class="flex items-center gap-3 p-3"><span class="w-8 h-8 rounded-lg bg-rose-50 text-rose-600 flex items-center justify-center"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg></span><div class="min-w-0 flex-1"><p class="text-sm font-medium text-gray-900 truncate">mockups.png</p><p class="text-xs text-gray-500">840 KB</p></div></div>
      </div>
    </div>
  </div>
</div>

<script>
  (function () {
    var list = document.querySelector('[aria-label="Project workspace"]');
    if (!list) return;
    var tabs = Array.prototype.slice.call(list.querySelectorAll('[role="tab"]'));
    var panels = tabs.map(function (t) { return document.getElementById(t.getAttribute('aria-controls')); });
    var indicator = list.querySelector('.a-indicator');
    function moveIndicator(tab) {
      if (!indicator) return;
      indicator.style.left = tab.offsetLeft + 'px';
      indicator.style.width = tab.offsetWidth + 'px';
    }
    function activate(tab) {
      tabs.forEach(function (t) {
        var s = t === tab;
        t.setAttribute('aria-selected', s); t.tabIndex = s ? 0 : -1;
        t.classList.toggle('text-gray-900', s); t.classList.toggle('text-gray-500', !s);
      });
      moveIndicator(tab);
      panels.forEach(function (p) { if (p) p.classList.add('hidden'); });
      var panel = document.getElementById(tab.getAttribute('aria-controls'));
      if (panel) panel.classList.remove('hidden');
    }
    tabs.forEach(function (tab, i) {
      tab.addEventListener('click', function () { activate(tab); });
      tab.addEventListener('keydown', function (e) {
        var idx = null;
        if (e.key === 'ArrowRight') idx = (i + 1) % tabs.length;
        if (e.key === 'ArrowLeft') idx = (i - 1 + tabs.length) % tabs.length;
        if (e.key === 'Home') idx = 0;
        if (e.key === 'End') idx = tabs.length - 1;
        if (idx !== null) { e.preventDefault(); tabs[idx].focus(); activate(tabs[idx]); }
      });
    });
    moveIndicator(tabs[0]);
    window.addEventListener('resize', function () {
      var active = list.querySelector('[aria-selected="true"]') || tabs[0];
      moveIndicator(active);
    });
  })();
</script>
92 lines UTF-8 · LF · Spaces: 2
DevSnips AI ready Claude · Cursor · Windsurf

Agent skill & Model Context Protocol

Pass this component straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.

devsnips://components/tabs
Prompt instruction
I want to use this DevSnips resource in production:

Page:
https://devsnips.site/library/tailwind/components/tabs/

Install: npx devsnips add
Tailwind/Components/Tabs

This is the Tabs — Complete tab component family with 15 production-ready variants covering documentation, dashboards, settings, mobile navigation, and animated indicators.

Use this DevSnips resource as the starting point for my project.
Adapt it to my project's stack and conventions, fix any issues,
and make it production-ready while preserving its intended design
and behavior.

Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.

Resource URI
devsnips://components/tabs