Tailwind CSS Glowing Gradient Border Button (Recipe)
The exact glowing-border pattern that ships in modern React/Next.js apps — an absolutely-positioned gradient layer, nudged out with -inset-0.5, blurred, and revealed on group-hover — implemented here in plain CSS line-for-line, with the equivalent Tailwind utility string documented so you can paste either version.
Published
The code
<section class="gbb-06" aria-label="Tailwind-style gradient blur glow button demo">
<div class="gbb-06__group">
<div class="gbb-06__glow" aria-hidden="true"></div><!-- absolute -inset-0.5 blur -->
<button class="gbb-06__btn" type="button">Deploy Now</button><!-- relative, on top -->
</div>
</section><section class="gbb-06" aria-label="Tailwind-style gradient blur glow button demo">
<div class="gbb-06__group">
<div class="gbb-06__glow" aria-hidden="true"></div><!-- absolute -inset-0.5 blur -->
<button class="gbb-06__btn" type="button">Deploy Now</button><!-- relative, on top -->
</div>
</section>.gbb-06,
.gbb-06 *,
.gbb-06 *::before,
.gbb-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gbb-06 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 48px 24px;
background: oklch(0.13 0.02 270);
}
.gbb-06 .gbb-06__group {
position: relative;
display: inline-block;
}
/* .relative.group */
.gbb-06 .gbb-06__glow {
position: absolute;
inset: -2px;
border-radius: 14px;
background: linear-gradient(90deg,oklch(0.65 0.26 328),oklch(0.75 0.15 195));
filter: blur(14px);
opacity: .6;
pointer-events: none;
transition: opacity .3s ease,scale .3s ease;
pointer-events: none;
}
/* .absolute.-inset-0.5.blur.opacity-60 */
.gbb-06 .gbb-06__group:hover .gbb-06__glow,
.gbb-06 .gbb-06__group:focus-within .gbb-06__glow {
opacity: 1;
scale: 1.02;
pointer-events: none;
}
/* .group-hover:opacity-100 */
.gbb-06 .gbb-06__btn {
position: relative;
cursor: pointer;
border: 1px solid rgba(255,255,255,.12);
border-radius: 12px;
padding: 16px 34px;
font: 600 15px/1 'Segoe UI',system-ui,sans-serif;
color: #fff;
background: oklch(0.15 0.02 270);
transition: transform .2s ease;
}
/* .relative.bg-slate-950 */
.gbb-06 .gbb-06__btn:hover {
transform: translateY(-1px);
}
.gbb-06 .gbb-06__btn:focus-visible {
outline: 2px solid oklch(0.75 0.15 195);
outline-offset: 4px;
}
.gbb-06 .gbb-06__btn:active {
transform: translateY(0) scale(.98);
}
@media (prefers-reduced-motion: reduce) {
.gbb-06 .gbb-06__glow,
.gbb-06 .gbb-06__btn {
transition: none;
}
}.gbb-06,
.gbb-06 *,
.gbb-06 *::before,
.gbb-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gbb-06 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 48px 24px;
background: oklch(0.13 0.02 270);
}
.gbb-06 .gbb-06__group {
position: relative;
display: inline-block;
}
/* .relative.group */
.gbb-06 .gbb-06__glow {
position: absolute;
inset: -2px;
border-radius: 14px;
background: linear-gradient(90deg,oklch(0.65 0.26 328),oklch(0.75 0.15 195));
filter: blur(14px);
opacity: .6;
pointer-events: none;
transition: opacity .3s ease,scale .3s ease;
pointer-events: none;
}
/* .absolute.-inset-0.5.blur.opacity-60 */
.gbb-06 .gbb-06__group:hover .gbb-06__glow,
.gbb-06 .gbb-06__group:focus-within .gbb-06__glow {
opacity: 1;
scale: 1.02;
pointer-events: none;
}
/* .group-hover:opacity-100 */
.gbb-06 .gbb-06__btn {
position: relative;
cursor: pointer;
border: 1px solid rgba(255,255,255,.12);
border-radius: 12px;
padding: 16px 34px;
font: 600 15px/1 'Segoe UI',system-ui,sans-serif;
color: #fff;
background: oklch(0.15 0.02 270);
transition: transform .2s ease;
}
/* .relative.bg-slate-950 */
.gbb-06 .gbb-06__btn:hover {
transform: translateY(-1px);
}
.gbb-06 .gbb-06__btn:focus-visible {
outline: 2px solid oklch(0.75 0.15 195);
outline-offset: 4px;
}
.gbb-06 .gbb-06__btn:active {
transform: translateY(0) scale(.98);
}
@media (prefers-reduced-motion: reduce) {
.gbb-06 .gbb-06__glow,
.gbb-06 .gbb-06__btn {
transition: none;
}
}/* No JavaScript — the canonical Tailwind two-layer pattern (relative group / absolute -inset blur layer / relative button) in plain CSS. */
/* No JavaScript — the canonical Tailwind two-layer pattern (relative group / absolute -inset blur layer / relative button) in plain CSS. */Here's a working CSS Glowing Border Button 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 CSS Glowing Gradient Border Button (Recipe)
Source: https://codefronts.com/components/css-glowing-border-buttons/tailwind-css-glowing-gradient-border-button-recipe/
The exact glowing-border pattern that ships in modern React/Next.js apps — an absolutely-positioned gradient layer, nudged out with -inset-0.5, blurred, and revealed on group-hover — implemented here in plain CSS line-for-line, with the equivalent Tailwind utility string documented so you can paste either version.
## HTML
```html
<section class="gbb-06" aria-label="Tailwind-style gradient blur glow button demo">
<div class="gbb-06__group">
<div class="gbb-06__glow" aria-hidden="true"></div><!-- absolute -inset-0.5 blur -->
<button class="gbb-06__btn" type="button">Deploy Now</button><!-- relative, on top -->
</div>
</section>
```
## CSS
```css
.gbb-06,
.gbb-06 *,
.gbb-06 *::before,
.gbb-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gbb-06 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 48px 24px;
background: oklch(0.13 0.02 270);
}
.gbb-06 .gbb-06__group {
position: relative;
display: inline-block;
}
/* .relative.group */
.gbb-06 .gbb-06__glow {
position: absolute;
inset: -2px;
border-radius: 14px;
background: linear-gradient(90deg,oklch(0.65 0.26 328),oklch(0.75 0.15 195));
filter: blur(14px);
opacity: .6;
pointer-events: none;
transition: opacity .3s ease,scale .3s ease;
pointer-events: none;
}
/* .absolute.-inset-0.5.blur.opacity-60 */
.gbb-06 .gbb-06__group:hover .gbb-06__glow,
.gbb-06 .gbb-06__group:focus-within .gbb-06__glow {
opacity: 1;
scale: 1.02;
pointer-events: none;
}
/* .group-hover:opacity-100 */
.gbb-06 .gbb-06__btn {
position: relative;
cursor: pointer;
border: 1px solid rgba(255,255,255,.12);
border-radius: 12px;
padding: 16px 34px;
font: 600 15px/1 'Segoe UI',system-ui,sans-serif;
color: #fff;
background: oklch(0.15 0.02 270);
transition: transform .2s ease;
}
/* .relative.bg-slate-950 */
.gbb-06 .gbb-06__btn:hover {
transform: translateY(-1px);
}
.gbb-06 .gbb-06__btn:focus-visible {
outline: 2px solid oklch(0.75 0.15 195);
outline-offset: 4px;
}
.gbb-06 .gbb-06__btn:active {
transform: translateY(0) scale(.98);
}
@media (prefers-reduced-motion: reduce) {
.gbb-06 .gbb-06__glow,
.gbb-06 .gbb-06__btn {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — the canonical Tailwind two-layer pattern (relative group / absolute -inset blur layer / relative button) in plain CSS. */
```Here's a working CSS Glowing Border Button 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 CSS Glowing Gradient Border Button (Recipe)
Source: https://codefronts.com/components/css-glowing-border-buttons/tailwind-css-glowing-gradient-border-button-recipe/
The exact glowing-border pattern that ships in modern React/Next.js apps — an absolutely-positioned gradient layer, nudged out with -inset-0.5, blurred, and revealed on group-hover — implemented here in plain CSS line-for-line, with the equivalent Tailwind utility string documented so you can paste either version.
## HTML
```html
<section class="gbb-06" aria-label="Tailwind-style gradient blur glow button demo">
<div class="gbb-06__group">
<div class="gbb-06__glow" aria-hidden="true"></div><!-- absolute -inset-0.5 blur -->
<button class="gbb-06__btn" type="button">Deploy Now</button><!-- relative, on top -->
</div>
</section>
```
## CSS
```css
.gbb-06,
.gbb-06 *,
.gbb-06 *::before,
.gbb-06 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gbb-06 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
padding: 48px 24px;
background: oklch(0.13 0.02 270);
}
.gbb-06 .gbb-06__group {
position: relative;
display: inline-block;
}
/* .relative.group */
.gbb-06 .gbb-06__glow {
position: absolute;
inset: -2px;
border-radius: 14px;
background: linear-gradient(90deg,oklch(0.65 0.26 328),oklch(0.75 0.15 195));
filter: blur(14px);
opacity: .6;
pointer-events: none;
transition: opacity .3s ease,scale .3s ease;
pointer-events: none;
}
/* .absolute.-inset-0.5.blur.opacity-60 */
.gbb-06 .gbb-06__group:hover .gbb-06__glow,
.gbb-06 .gbb-06__group:focus-within .gbb-06__glow {
opacity: 1;
scale: 1.02;
pointer-events: none;
}
/* .group-hover:opacity-100 */
.gbb-06 .gbb-06__btn {
position: relative;
cursor: pointer;
border: 1px solid rgba(255,255,255,.12);
border-radius: 12px;
padding: 16px 34px;
font: 600 15px/1 'Segoe UI',system-ui,sans-serif;
color: #fff;
background: oklch(0.15 0.02 270);
transition: transform .2s ease;
}
/* .relative.bg-slate-950 */
.gbb-06 .gbb-06__btn:hover {
transform: translateY(-1px);
}
.gbb-06 .gbb-06__btn:focus-visible {
outline: 2px solid oklch(0.75 0.15 195);
outline-offset: 4px;
}
.gbb-06 .gbb-06__btn:active {
transform: translateY(0) scale(.98);
}
@media (prefers-reduced-motion: reduce) {
.gbb-06 .gbb-06__glow,
.gbb-06 .gbb-06__btn {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — the canonical Tailwind two-layer pattern (relative group / absolute -inset blur layer / relative button) in plain CSS. */
```How this works
The Tailwind community converged on a two-layer structure: a relative group wrapper, a decorative absolute -inset-0.5 bg-gradient-to-r … rounded-xl blur opacity-60 group-hover:opacity-100 transition div behind, and the real button on top with relative + a solid dark fill. The blur turns the oversized gradient into a soft aura; because the gradient sticks out 2px on every side, its unblurred edge also reads as a crisp gradient border. This demo is that structure in vanilla CSS — same layer names in comments — so you can learn it once and write it in either dialect.
The Tailwind version, verbatim:
<div class="relative group">
<div class="absolute -inset-0.5 rounded-xl blur
bg-gradient-to-r from-fuchsia-500 to-cyan-500
opacity-60 group-hover:opacity-100
transition duration-300" aria-hidden="true"></div>
<button class="relative rounded-xl bg-slate-950 px-8 py-4
text-white font-semibold">Deploy Now</button>
</div>The hover also scales the glow layer to 1.02 — a detail utilities can do with group-hover:scale-[1.02] — which makes the aura feel like it's swelling toward the cursor.
Make it yours
- Gradient stops map 1:1 to Tailwind's
from-*/to-*; add avia-*(third stop) for richer auras. blur(14px)≈ Tailwind'sblur; useblur-md/blur-lgequivalents (12/16px) to taste.- Resting
opacity:.6= always-glowing CTA; start at 0 for a reveal-on-hover secondary button. - In React, extract the pair into a
<GlowButton>component and pass the gradient as a prop.
Gotchas — read before shipping
- The glow div must be
aria-hiddenandpointer-events:none— it sits in the DOM, and screen readers/clicks will find it otherwise. - Both layers need matching border-radius or the glow corners peek out square.
- Don't put the blur on the button itself — it would blur the label; the two-layer split is the point.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 15.4+ | 113+ | 111+ |
Floor set by oklch() as this demo is written. The core technique itself goes back further — Chrome 76+.
Just filter:blur + opacity transitions — the most compatible glow in this collection. Works in every Tailwind-era browser.