25 Tailwind CSS Button Groups
06 / 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 Split Button Dropdown with Native Details Menu (Save Options)

The universal split button — primary Save plus a caret menu — built on <details>/<summary>, which works in every browser with zero script. group-open/more: rotates the chevron and plays the menu's entrance (animate-tbg06-in), the marker is removed with list-none [&::-webkit-details-marker]:hidden, and each item shows its keyboard shortcut.

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-06 w-full min-h-svh grid justify-items-center content-start bg-tbg06-bg bg-linear-160 from-tbg06-bg to-tbg06-bg2 px-5 pt-32 pb-16 font-tbg06-sans text-tbg06-ink" aria-label="Split button dropdown demo">
  <div class="relative inline-flex rounded-2xl shadow-tbg06-lift">
    <button type="button" class="inline-flex h-12 cursor-pointer items-center gap-2.5 rounded-l-2xl bg-tbg06-acc pr-5 pl-4.5 text-[15.5px] font-bold text-tbg06-ink transition hover:brightness-105 active:brightness-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tbg06-ink">
      <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 4h11l3 3v13H5z"/><path d="M8 4v5h7V4M8 20v-6h8v6"/></svg>
      Save changes
    </button>
    <details class="group/more relative">
      <summary aria-label="More save options" class="grid h-12 w-12 cursor-pointer list-none place-items-center rounded-r-2xl border-l border-tbg06-ink/20 bg-tbg06-acc-d text-tbg06-ink transition hover:brightness-105 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tbg06-ink [&::-webkit-details-marker]:hidden">
        <svg class="transition-transform duration-300 group-open/more:-rotate-180 motion-reduce:transition-none" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
      </summary>
      <div class="absolute top-[calc(100%+0.5rem)] right-0 z-20 hidden w-64 flex-col gap-0.5 rounded-2xl border border-tbg06-line bg-white p-1.5 shadow-tbg06-menu group-open/more:flex group-open/more:animate-tbg06-in motion-reduce:animate-none">
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save as… <kbd class="ml-auto font-sans text-xs font-medium text-tbg06-mut">⇧⌘S</kbd></button>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save a copy <kbd class="ml-auto font-sans text-xs font-medium text-tbg06-mut">⌥⌘S</kbd></button>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save as template</button>
        <div role="separator" class="mx-2 my-1.5 h-px bg-tbg06-line"></div>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center gap-2.5 rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-danger hover:bg-tbg06-danger/8 focus-visible:bg-tbg06-danger/8 focus-visible:outline-2 focus-visible:outline-tbg06-danger"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3"/></svg>Discard changes</button>
      </div>
    </details>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tbg06-bg: #fff7ea;
  --color-tbg06-bg2: #ffedd0;
  --color-tbg06-ink: #3a2508;
  --color-tbg06-body: #4f3714;
  --color-tbg06-mut: #82694a;
  --color-tbg06-mut: oklch(0.53 0.05 70);
  --color-tbg06-line: #f0dcbb;
  --color-tbg06-tint: #fdf1dd;
  --color-tbg06-acc: #f7a23a;
  --color-tbg06-acc: oklch(0.77 0.15 65);
  --color-tbg06-acc-d: #e48a1c;
  --color-tbg06-acc-d: oklch(0.7 0.16 60);
  --color-tbg06-danger: #b23b2e;
  --color-tbg06-danger: oklch(0.5 0.16 30);
  --shadow-tbg06-lift: 0 12px 30px -14px rgb(150 90 10 / 0.7);
  --shadow-tbg06-menu: 0 24px 50px -22px rgb(120 70 5 / 0.55);
  --font-tbg06-sans: 'Bricolage Grotesque', system-ui, sans-serif;
  --animate-tbg06-in: tbg06-in 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);

  @keyframes tbg06-in {
    from {
      opacity: 0;
      translate: 0 -8px;
    }

    to {
      opacity: 1;
      translate: 0 0;
    }
  }
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

.tbg-06 {
  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-tbg06-bg: #fff7ea;
  --color-tbg06-bg2: #ffedd0;
  --color-tbg06-ink: #3a2508;
  --color-tbg06-body: #4f3714;
  --color-tbg06-mut: #82694a;
  --color-tbg06-mut: oklch(0.53 0.05 70);
  --color-tbg06-line: #f0dcbb;
  --color-tbg06-tint: #fdf1dd;
  --color-tbg06-acc: #f7a23a;
  --color-tbg06-acc: oklch(0.77 0.15 65);
  --color-tbg06-acc-d: #e48a1c;
  --color-tbg06-acc-d: oklch(0.7 0.16 60);
  --color-tbg06-danger: #b23b2e;
  --color-tbg06-danger: oklch(0.5 0.16 30);
  --shadow-tbg06-lift: 0 12px 30px -14px rgb(150 90 10 / 0.7);
  --shadow-tbg06-menu: 0 24px 50px -22px rgb(120 70 5 / 0.55);
  --font-tbg06-sans: 'Bricolage Grotesque', system-ui, sans-serif;
  --animate-tbg06-in: tbg06-in 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);

  @keyframes tbg06-in {
    from {
      opacity: 0;
      translate: 0 -8px;
    }

    to {
      opacity: 1;
      translate: 0 0;
    }
  }
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

.tbg-06 {
  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=Bricolage+Grotesque:opsz,wght@12..96,400..800&display=swap">

What changed in the port

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

  • .btn-06__more[open] .btn-06__caret::after{…} became group-open/more:-rotate-180 on a real SVG chevron (crisper than the bordered pseudo-element at any zoom).
  • The ::-webkit-details-marker + ::marker pair became list-none [&::-webkit-details-marker]:hidden.
  • UI upgrade: the primary action gained a save icon, items show keyboard shortcuts, and Discard got a trash icon plus a tinted danger hover.
  • UI upgrade: the caret ink sits on a slightly lighter amber than before, raising icon contrast to 6:1, and muted text now reaches 4.6:1 on white.
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 Split Button Dropdown with Native Details Menu (Save Options)
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-split-button-dropdown-details/

The universal split button — primary Save plus a caret menu — built on <details>/<summary>, which works in every browser with zero script. group-open/more: rotates the chevron and plays the menu's entrance (animate-tbg06-in), the marker is removed with list-none [&::-webkit-details-marker]:hidden, and each item shows its keyboard shortcut.
## HTML
```html
<section class="tbg-06 w-full min-h-svh grid justify-items-center content-start bg-tbg06-bg bg-linear-160 from-tbg06-bg to-tbg06-bg2 px-5 pt-32 pb-16 font-tbg06-sans text-tbg06-ink" aria-label="Split button dropdown demo">
  <div class="relative inline-flex rounded-2xl shadow-tbg06-lift">
    <button type="button" class="inline-flex h-12 cursor-pointer items-center gap-2.5 rounded-l-2xl bg-tbg06-acc pr-5 pl-4.5 text-[15.5px] font-bold text-tbg06-ink transition hover:brightness-105 active:brightness-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tbg06-ink">
      <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 4h11l3 3v13H5z"/><path d="M8 4v5h7V4M8 20v-6h8v6"/></svg>
      Save changes
    </button>
    <details class="group/more relative">
      <summary aria-label="More save options" class="grid h-12 w-12 cursor-pointer list-none place-items-center rounded-r-2xl border-l border-tbg06-ink/20 bg-tbg06-acc-d text-tbg06-ink transition hover:brightness-105 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tbg06-ink [&::-webkit-details-marker]:hidden">
        <svg class="transition-transform duration-300 group-open/more:-rotate-180 motion-reduce:transition-none" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
      </summary>
      <div class="absolute top-[calc(100%+0.5rem)] right-0 z-20 hidden w-64 flex-col gap-0.5 rounded-2xl border border-tbg06-line bg-white p-1.5 shadow-tbg06-menu group-open/more:flex group-open/more:animate-tbg06-in motion-reduce:animate-none">
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save as… <kbd class="ml-auto font-sans text-xs font-medium text-tbg06-mut">⇧⌘S</kbd></button>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save a copy <kbd class="ml-auto font-sans text-xs font-medium text-tbg06-mut">⌥⌘S</kbd></button>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-body hover:bg-tbg06-tint focus-visible:bg-tbg06-tint focus-visible:outline-2 focus-visible:outline-tbg06-acc-d">Save as template</button>
        <div role="separator" class="mx-2 my-1.5 h-px bg-tbg06-line"></div>
        <button type="button" class="flex min-h-11 w-full cursor-pointer items-center gap-2.5 rounded-xl px-3 text-left text-[14.5px] font-semibold text-tbg06-danger hover:bg-tbg06-danger/8 focus-visible:bg-tbg06-danger/8 focus-visible:outline-2 focus-visible:outline-tbg06-danger"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3"/></svg>Discard changes</button>
      </div>
    </details>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbg06-bg: #fff7ea;
  --color-tbg06-bg2: #ffedd0;
  --color-tbg06-ink: #3a2508;
  --color-tbg06-body: #4f3714;
  --color-tbg06-mut: #82694a;
  --color-tbg06-mut: oklch(0.53 0.05 70);
  --color-tbg06-line: #f0dcbb;
  --color-tbg06-tint: #fdf1dd;
  --color-tbg06-acc: #f7a23a;
  --color-tbg06-acc: oklch(0.77 0.15 65);
  --color-tbg06-acc-d: #e48a1c;
  --color-tbg06-acc-d: oklch(0.7 0.16 60);
  --color-tbg06-danger: #b23b2e;
  --color-tbg06-danger: oklch(0.5 0.16 30);
  --shadow-tbg06-lift: 0 12px 30px -14px rgb(150 90 10 / 0.7);
  --shadow-tbg06-menu: 0 24px 50px -22px rgb(120 70 5 / 0.55);
  --font-tbg06-sans: 'Bricolage Grotesque', system-ui, sans-serif;
  --animate-tbg06-in: tbg06-in 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);

  @keyframes tbg06-in {
    from {
      opacity: 0;
      translate: 0 -8px;
    }

    to {
      opacity: 1;
      translate: 0 0;
    }
  }
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */

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

How this works

<details> is the state machine. Clicking the summary toggles [open]; Tailwind's open: variant (and group-open/name: for descendants) reads it:

<details class="group/more relative">
  <summary class="list-none [&::-webkit-details-marker]:hidden">
    <svg class="group-open/more:-rotate-180">…
  <div class="hidden group-open/more:flex group-open/more:animate-tbg06-in">

The animation is a token. --animate-tbg06-in: tbg06-in .22s … in @theme mints animate-tbg06-in, and its keyframes are only emitted because a class uses it.

Make it yours

  • Open upwards: bottom-[calc(100%+0.5rem)] instead of top-[…].
  • Change the destructive item colour via --color-tbg06-danger.
  • Left-align the menu with the primary button: left-0 on the menu and move relative to the wrapper.

Gotchas — read before shipping

  • <details> doesn't light-dismiss: an outside click leaves it open. Use the Popover version (demo 01) when that matters.
  • Items are buttons, not true ARIA menu items with arrow keys — fine for a short list, script it for long ones.
  • Keep the primary action outside <details> so it never toggles the menu.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

<details> is universal; the floor is Tailwind v4's generated sheet.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Plain CSSno Tailwind surface

Search CodeFronts

Loading…