25 Tailwind CSS Button Groups
13 / 25

All 25 in 25 Tailwind CSS Button Groups

  1. 01Tailwind Split Button with Anchor-Positioned Popover Dropdown (No JS)
  2. 02Tailwind Segmented Control with Motion-Path Comet Indicator
  3. 03Tailwind Toggle Button Group with View Transitions Morphing Highlight
  4. 04Tailwind Pricing Toggle — Monthly / Yearly Billing Switch (No JS)
  5. 05Tailwind Segmented Control with Sliding Thumb (iOS Style)
  6. 06Tailwind Split Button Dropdown with Native Details Menu (Save Options)
  7. 07Tailwind Icon Button Group Toolbar with Tooltips (Rich Text Editor)
  8. 08Tailwind Pill Filter Button Group with Sliding Indicator (Anchor Positioning)
  9. 09Tailwind Toggle Button Group for Text Alignment (Radio Inputs, Live Preview)
  10. 10Tailwind Web3 Connect Wallet Button Grid (Wallet Sign-In Modal)
  11. 11Tailwind AI Model Selector Button Group (LLM Model Picker with Badges)
  12. 12Tailwind Liquid Metal Segmented Control (Animated Chrome Thumb)
  13. 13Tailwind Tab Button Group with Subgrid Underline Indicator
  14. 14Tailwind Multi-Select Chip Buttons (Tag Filter Checkboxes with Count)
  15. 15Tailwind Animated Split Button Deploy Menu (Staggered Dropdown Reveal)
  16. 16Tailwind Radio Button Group with Conic Fill Animation (Export Format Picker)
  17. 17Tailwind Retro LED Pixel Button Group (Dot-Matrix Display Buttons)
  18. 18Tailwind Hold-to-Confirm Button Group with Gradient Progress (Press and Hold)
  19. 19Tailwind Holographic Icon Segmented Control (Grid / List View Switcher)
  20. 20Tailwind 3D Vertical Button Group with Hover Depth (Perspective Stack)
  21. 21Tailwind Floating Action Button with Radial Speed Dial Menu (No JS)
  22. 22Tailwind Glitch Effect Button Group (Cyberpunk RGB-Split Audio Filter)
  23. 23Tailwind Animated Gradient Border Pill Buttons (Rotating Conic Ring)
  24. 24Tailwind Button Group with Ripple Click Effect (Radar Shockwave Feedback)
  25. 25Tailwind Button Group with Cursor-Following Spotlight Glow (Date Range Presets)
Pure TailwindMIT licensed

Tailwind Tab Button Group with Subgrid Underline Indicator

Dashboard tabs with a glowing underline that always matches each tab's exact width — because the underline row shares the tabs' columns through grid-cols-subgrid. The CSS original moved one beam between columns, which can't animate; this port gives every column its own beam segment, so the old one shrinks out while the new one grows in — a smooth hand-off, still with zero JavaScript.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tbg-13 w-full min-h-svh grid place-items-center bg-tbg13-bg bg-linear-180 from-tbg13-bg to-tbg13-bg2 px-5 py-14 font-tbg13-sans text-tbg13-ink" aria-label="Subgrid underline tabs demo">
  <div class="w-full max-w-[38rem] overflow-x-auto pb-2">
    <div role="radiogroup" aria-label="Dashboard sections" class="group/tabs grid w-fit grid-cols-[repeat(4,auto)] gap-x-1.5 border-b border-white/8">
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-1" class="sr-only" checked>Overview</label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-2" class="sr-only">Analytics <span class="rounded-full bg-tbg13-acc/18 px-1.5 text-[11px] font-bold text-tbg13-acc">New</span></label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-3" class="sr-only">Reports <span class="rounded-full bg-white/8 px-1.5 text-[11px] font-bold tabular-nums">3</span></label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-4" class="sr-only">Settings</label>
      <div aria-hidden="true" class="col-span-full row-start-2 -mb-px grid h-[5px] grid-cols-subgrid not-supports-[grid-template-columns:subgrid]:grid-cols-4">
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-1:checked]/tabs:scale-x-100 group-has-[#tbg13-1:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-2:checked]/tabs:scale-x-100 group-has-[#tbg13-2:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-3:checked]/tabs:scale-x-100 group-has-[#tbg13-3:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-4:checked]/tabs:scale-x-100 group-has-[#tbg13-4:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
      </div>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tbg13-bg: #12100e;
  --color-tbg13-bg2: #191510;
  --color-tbg13-ink: #f4ede4;
  --color-tbg13-mut: #a79c90;
  --color-tbg13-mut: oklch(0.7 0.02 70);
  --color-tbg13-hover: #e1d7ca;
  --color-tbg13-acc: #ff7d2e;
  --color-tbg13-acc: oklch(0.72 0.19 45);
  --shadow-tbg13-glow: 0 0 16px 1px var(--color-tbg13-acc), 0 0 40px 2px color-mix(in oklab, var(--color-tbg13-acc) 60%, transparent);
  --font-tbg13-sans: 'Archivo', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

.tbg-13 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tbg13-bg: #12100e;
  --color-tbg13-bg2: #191510;
  --color-tbg13-ink: #f4ede4;
  --color-tbg13-mut: #a79c90;
  --color-tbg13-mut: oklch(0.7 0.02 70);
  --color-tbg13-hover: #e1d7ca;
  --color-tbg13-acc: #ff7d2e;
  --color-tbg13-acc: oklch(0.72 0.19 45);
  --shadow-tbg13-glow: 0 0 16px 1px var(--color-tbg13-acc), 0 0 40px 2px color-mix(in oklab, var(--color-tbg13-acc) 60%, transparent);
  --font-tbg13-sans: 'Archivo', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

.tbg-13 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<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=Archivo:wdth,wght@62..125,400..800&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • The track's grid-template-columns:subgrid became grid-cols-subgrid; the @supports not fallback became not-supports-[…]:grid-cols-4.
  • UI upgrade: the single teleporting beam (its transition:grid-column could never animate) became four scaling segments, so switching tabs is now a smooth hand-off.
  • UI upgrade: tabs carry a “New” badge and a count, a baseline rule anchors the group, and the row scrolls instead of overflowing on phones.
  • UI upgrade: inactive tabs rose from #8f857a to oklch(0.7) (7:1), and Archivo's wide axis gives the labels a dashboard voice.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Tab Button Group with Subgrid Underline Indicator
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-tabs-subgrid-underline-indicator/

Dashboard tabs with a glowing underline that always matches each tab's exact width — because the underline row shares the tabs' columns through grid-cols-subgrid. The CSS original moved one beam between columns, which can't animate; this port gives every column its own beam segment, so the old one shrinks out while the new one grows in &mdash; a smooth hand-off, still with zero JavaScript.
## HTML
```html
<section class="tbg-13 w-full min-h-svh grid place-items-center bg-tbg13-bg bg-linear-180 from-tbg13-bg to-tbg13-bg2 px-5 py-14 font-tbg13-sans text-tbg13-ink" aria-label="Subgrid underline tabs demo">
  <div class="w-full max-w-[38rem] overflow-x-auto pb-2">
    <div role="radiogroup" aria-label="Dashboard sections" class="group/tabs grid w-fit grid-cols-[repeat(4,auto)] gap-x-1.5 border-b border-white/8">
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-1" class="sr-only" checked>Overview</label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-2" class="sr-only">Analytics <span class="rounded-full bg-tbg13-acc/18 px-1.5 text-[11px] font-bold text-tbg13-acc">New</span></label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-3" class="sr-only">Reports <span class="rounded-full bg-white/8 px-1.5 text-[11px] font-bold tabular-nums">3</span></label>
      <label class="relative row-start-1 flex min-h-12 cursor-pointer items-center gap-2 rounded-lg px-4.5 text-[15.5px] font-semibold [font-stretch:110%] text-tbg13-mut transition-colors duration-250 hover:text-tbg13-hover has-checked:text-white has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-tbg13-acc"><input type="radio" name="tbg13" id="tbg13-4" class="sr-only">Settings</label>
      <div aria-hidden="true" class="col-span-full row-start-2 -mb-px grid h-[5px] grid-cols-subgrid not-supports-[grid-template-columns:subgrid]:grid-cols-4">
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-1:checked]/tabs:scale-x-100 group-has-[#tbg13-1:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-2:checked]/tabs:scale-x-100 group-has-[#tbg13-2:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-3:checked]/tabs:scale-x-100 group-has-[#tbg13-3:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
        <span class="scale-x-0 rounded-full bg-tbg13-acc opacity-0 shadow-tbg13-glow transition-[scale,opacity] duration-400 ease-[cubic-bezier(.3,.7,.3,1)] group-has-[#tbg13-4:checked]/tabs:scale-x-100 group-has-[#tbg13-4:checked]/tabs:opacity-100 motion-reduce:transition-none"></span>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbg13-bg: #12100e;
  --color-tbg13-bg2: #191510;
  --color-tbg13-ink: #f4ede4;
  --color-tbg13-mut: #a79c90;
  --color-tbg13-mut: oklch(0.7 0.02 70);
  --color-tbg13-hover: #e1d7ca;
  --color-tbg13-acc: #ff7d2e;
  --color-tbg13-acc: oklch(0.72 0.19 45);
  --shadow-tbg13-glow: 0 0 16px 1px var(--color-tbg13-acc), 0 0 40px 2px color-mix(in oklab, var(--color-tbg13-acc) 60%, transparent);
  --font-tbg13-sans: 'Archivo', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

.tbg-13 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

Subgrid shares the columns. The tabs sit in row 1 of an auto-sized grid; the track spans every column on row 2 and adopts them:

<div class="col-span-full row-start-2 grid grid-cols-subgrid">
  <span class="scale-x-0 group-has-[#tbg13-1:checked]/tabs:scale-x-100"></span>
  <span class="scale-x-0 group-has-[#tbg13-2:checked]/tabs:scale-x-100"></span>…

Why four beams. grid-column is not animatable, so the original's beam teleported. Four segments that scale in and out are animatable, and each still fits its tab exactly.

Make it yours

  • Slide-from-left feel: set origin-left on the beams.
  • Pill tabs: drop the track and add has-checked:bg-white/8 rounded-lg to tabs.
  • Re-theme via --color-tbg13-acc; the glow follows.

Gotchas — read before shipping

  • Radios model a selection, not ARIA tabs — for tab panels with role="tab" semantics, script the full pattern.
  • Tabs must stay in one row for subgrid alignment; on small screens let the group scroll horizontally (overflow-x-auto).
  • Keep labels' row-start-1: without it, auto-placement can drop a tab into row 2.

Browser support

ChromeSafariFirefoxEdge
117+16+71+117+

Subgrid is Baseline 2023; Tailwind v4 sets the floor. Without subgrid, beams fall back to equal columns.

Techniques used in this demo

Search CodeFronts

Loading…