23 / 25
All 25 in 25 Tailwind CSS Button Groups
- 01Tailwind Split Button with Anchor-Positioned Popover Dropdown (No JS)
- 02Tailwind Segmented Control with Motion-Path Comet Indicator
- 03Tailwind Toggle Button Group with View Transitions Morphing Highlight
- 04Tailwind Pricing Toggle — Monthly / Yearly Billing Switch (No JS)
- 05Tailwind Segmented Control with Sliding Thumb (iOS Style)
- 06Tailwind Split Button Dropdown with Native Details Menu (Save Options)
- 07Tailwind Icon Button Group Toolbar with Tooltips (Rich Text Editor)
- 08Tailwind Pill Filter Button Group with Sliding Indicator (Anchor Positioning)
- 09Tailwind Toggle Button Group for Text Alignment (Radio Inputs, Live Preview)
- 10Tailwind Web3 Connect Wallet Button Grid (Wallet Sign-In Modal)
- 11Tailwind AI Model Selector Button Group (LLM Model Picker with Badges)
- 12Tailwind Liquid Metal Segmented Control (Animated Chrome Thumb)
- 13Tailwind Tab Button Group with Subgrid Underline Indicator
- 14Tailwind Multi-Select Chip Buttons (Tag Filter Checkboxes with Count)
- 15Tailwind Animated Split Button Deploy Menu (Staggered Dropdown Reveal)
- 16Tailwind Radio Button Group with Conic Fill Animation (Export Format Picker)
- 17Tailwind Retro LED Pixel Button Group (Dot-Matrix Display Buttons)
- 18Tailwind Hold-to-Confirm Button Group with Gradient Progress (Press and Hold)
- 19Tailwind Holographic Icon Segmented Control (Grid / List View Switcher)
- 20Tailwind 3D Vertical Button Group with Hover Depth (Perspective Stack)
- 21Tailwind Floating Action Button with Radial Speed Dial Menu (No JS)
- 22Tailwind Glitch Effect Button Group (Cyberpunk RGB-Split Audio Filter)
- 23Tailwind Animated Gradient Border Pill Buttons (Rotating Conic Ring)
- 24Tailwind Button Group with Ripple Click Effect (Radar Shockwave Feedback)
- 25Tailwind Button Group with Cursor-Following Spotlight Glow (Date Range Presets)
Tailwind Animated Gradient Border Pill Buttons (Rotating Conic Ring)
Plan-selector pills ringed by a rotating conic-gradient border — slow violet for idle pills, a fast solar ring plus blurred halo for the chosen one. The border is the padding-box/border-box trick in a single arbitrary [background:…], spun by an @property angle. The CSS original's halo used z-index:-1 and vanished behind the page background; an isolate wrapper fixes it.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tbg-23 w-full min-h-svh grid place-items-center bg-tbg23-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg23-glow),transparent_70%)] px-5 py-14 font-tbg23-sans text-tbg23-ink" aria-label="Animated gradient border pill buttons demo">
<div class="grid w-full max-w-[34rem] gap-4">
<p id="tbg23-label" class="ml-0.5 font-tbg23-display text-xs font-medium uppercase tracking-[0.16em] text-tbg23-acc">Energy plan</p>
<div role="radiogroup" aria-labelledby="tbg23-label" class="isolate flex flex-wrap gap-4">
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only" checked><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>Solar</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="1.8" fill="currentColor"/><ellipse cx="12" cy="12" rx="9" ry="3.6"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(120 12 12)"/></svg>Fusion</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><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 19c0-8 5-13 14-14-1 9-6 14-14 14zM5 19l7-7"/></svg>Hybrid</label>
</div>
</div>
</section><section class="tbg-23 w-full min-h-svh grid place-items-center bg-tbg23-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg23-glow),transparent_70%)] px-5 py-14 font-tbg23-sans text-tbg23-ink" aria-label="Animated gradient border pill buttons demo">
<div class="grid w-full max-w-[34rem] gap-4">
<p id="tbg23-label" class="ml-0.5 font-tbg23-display text-xs font-medium uppercase tracking-[0.16em] text-tbg23-acc">Energy plan</p>
<div role="radiogroup" aria-labelledby="tbg23-label" class="isolate flex flex-wrap gap-4">
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only" checked><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>Solar</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="1.8" fill="currentColor"/><ellipse cx="12" cy="12" rx="9" ry="3.6"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(120 12 12)"/></svg>Fusion</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><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 19c0-8 5-13 14-14-1 9-6 14-14 14zM5 19l7-7"/></svg>Hybrid</label>
</div>
</div>
</section>@import "tailwindcss";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}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";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}<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=Unbounded:wght@400..700&family=Manrope:wght@400..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=Unbounded:wght@400..700&family=Manrope:wght@400..800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The padding-box/border-box ring moved verbatim into an arbitrary
[background:…]property; slow and fast spins are two tokens sharing one keyframe. - Bug fix: the original halo (
z-index:-1, no stacking context) rendered behind the section background and never showed;isolateon the group restores it. - UI upgrade: each plan gained an icon (sun, atom, leaf), and pills are 52px tall.
- UI upgrade: idle text rose from
#b9a8cftooklch(0.8)(9:1), and the label is set in Unbounded for a stronger voice.
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 Gradient Border Pill Buttons (Rotating Conic Ring)
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-animated-gradient-border-pill-buttons/
Plan-selector pills ringed by a rotating conic-gradient border — slow violet for idle pills, a fast solar ring plus blurred halo for the chosen one. The border is the padding-box/border-box trick in a single arbitrary [background:…], spun by an @property angle. The CSS original's halo used z-index:-1 and vanished behind the page background; an isolate wrapper fixes it.
## HTML
```html
<section class="tbg-23 w-full min-h-svh grid place-items-center bg-tbg23-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg23-glow),transparent_70%)] px-5 py-14 font-tbg23-sans text-tbg23-ink" aria-label="Animated gradient border pill buttons demo">
<div class="grid w-full max-w-[34rem] gap-4">
<p id="tbg23-label" class="ml-0.5 font-tbg23-display text-xs font-medium uppercase tracking-[0.16em] text-tbg23-acc">Energy plan</p>
<div role="radiogroup" aria-labelledby="tbg23-label" class="isolate flex flex-wrap gap-4">
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only" checked><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>Solar</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="1.8" fill="currentColor"/><ellipse cx="12" cy="12" rx="9" ry="3.6"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(120 12 12)"/></svg>Fusion</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><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 19c0-8 5-13 14-14-1 9-6 14-14 14zM5 19l7-7"/></svg>Hybrid</label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}
```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 Gradient Border Pill Buttons (Rotating Conic Ring)
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-animated-gradient-border-pill-buttons/
Plan-selector pills ringed by a rotating conic-gradient border — slow violet for idle pills, a fast solar ring plus blurred halo for the chosen one. The border is the padding-box/border-box trick in a single arbitrary [background:…], spun by an @property angle. The CSS original's halo used z-index:-1 and vanished behind the page background; an isolate wrapper fixes it.
## HTML
```html
<section class="tbg-23 w-full min-h-svh grid place-items-center bg-tbg23-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg23-glow),transparent_70%)] px-5 py-14 font-tbg23-sans text-tbg23-ink" aria-label="Animated gradient border pill buttons demo">
<div class="grid w-full max-w-[34rem] gap-4">
<p id="tbg23-label" class="ml-0.5 font-tbg23-display text-xs font-medium uppercase tracking-[0.16em] text-tbg23-acc">Energy plan</p>
<div role="radiogroup" aria-labelledby="tbg23-label" class="isolate flex flex-wrap gap-4">
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only" checked><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>Solar</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="1.8" fill="currentColor"/><ellipse cx="12" cy="12" rx="9" ry="3.6"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="9" ry="3.6" transform="rotate(120 12 12)"/></svg>Fusion</label>
<label class="relative flex min-h-13 cursor-pointer items-center gap-2.5 rounded-full border-2 border-transparent px-7 text-[15px] font-bold text-tbg23-mut animate-tbg23-spin transition-colors duration-250 [background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box] hover:text-tbg23-ink has-checked:animate-tbg23-spin-fast has-checked:text-white has-checked:[background:linear-gradient(var(--color-tbg23-pill-on),var(--color-tbg23-pill-on))_padding-box,conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)_border-box] has-checked:before:absolute has-checked:before:-inset-1 has-checked:before:-z-1 has-checked:before:rounded-full has-checked:before:bg-[conic-gradient(from_var(--tbg23-a),#ff7a18,#ff2bd0,#ffd24c,#ff7a18)] has-checked:before:opacity-55 has-checked:before:blur-[11px] has-checked:before:animate-tbg23-spin-fast has-checked:before:content-[''] has-focus-visible:outline-3 has-focus-visible:outline-offset-4 has-focus-visible:outline-tbg23-sun motion-reduce:animate-none! motion-reduce:before:animate-none!"><input type="radio" name="tbg23" class="sr-only"><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 19c0-8 5-13 14-14-1 9-6 14-14 14zM5 19l7-7"/></svg>Hybrid</label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
/* @property is an at-rule with no utility: it makes the ring angle animatable. */
@property --tbg23-a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@theme {
--color-tbg23-bg: #08040c;
--color-tbg23-glow: #1a0d23;
--color-tbg23-pill: #160c1f;
--color-tbg23-pill-on: #1d0f15;
--color-tbg23-ink: #f0e6ff;
--color-tbg23-mut: #c6b6dc;
--color-tbg23-mut: oklch(0.8 0.05 300);
--color-tbg23-acc: #d59bff;
--color-tbg23-sun: #ffd24c;
--font-tbg23-sans: 'Manrope', system-ui, sans-serif;
--font-tbg23-display: 'Unbounded', system-ui, sans-serif;
--animate-tbg23-spin: tbg23-spin 7s linear infinite;
--animate-tbg23-spin-fast: tbg23-spin 3s linear infinite;
@keyframes tbg23-spin {
to {
--tbg23-a: 360deg;
}
}
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-23 {
width: 100%;
min-height: 100svh;
}
```How this works
Two backgrounds, one border. A solid fill clipped to the padding box sits over a conic gradient clipped to the border box; a transparent 2px border lets the ring show:
<label class="border-2 border-transparent animate-tbg23-spin
[background:linear-gradient(var(--color-tbg23-pill),var(--color-tbg23-pill))_padding-box,
conic-gradient(from_var(--tbg23-a),#5b3a8a,#8a5bd6,#3a5b8a,#5b3a8a)_border-box]">The halo bug. A -z-1 pseudo-element paints beneath the nearest stacking context. Without one, that's the page — under the section's background. isolate on the pill group creates a local context so the glow sits just behind the pill.
Make it yours
- Ring thickness:
border-2→border-[3px]. - Idle pills static: drop
animate-tbg23-spinfrom unchecked pills. - Your palette: edit the conic stops in the checked state.
Gotchas — read before shipping
@propertymust stay outside@theme.- Three spinning rings are cheap; dozens on one page are not — pause idle ones if you scale up.
- All animation stops under
motion-reduce:; the rings remain as static gradients.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
@property is Baseline 2024; without it rings render static.