Experiment #002
Glow Button
A blurred layer sits behind the button and fades in on hover or keyboard focus, while the border brightens in sync. The glow is a separate element (or pseudo-element in the CSS variant), so only opacity animates — no repaint-heavy box-shadow transition. Works on light and dark backgrounds with a single accent color.
Scene
Technical details
- Experiment
- FX-002
- Category
- Buttons
- Stack
- Tailwind + CSS
- Difficulty
- Beginner
- Dependencies
- none
- Weight
- HTML 1.0 KB · CSS 1.1 KB
- Added
- 2026-08-21
- Updated
- 2026-08-21
Lab notes
Keep the glow opacity between 0.4 and 0.7 — past that it reads as neon. Tune the spread with the blur radius (8–16px) and the negative inset of the glow layer, not with a larger element.
Take the code
HTML — code.html
<!-- Glow Button — Tailwind CSS -->
<button
type="button"
class="group relative rounded-md focus-visible:outline-2 focus-visible:outline-offset-4
focus-visible:outline-indigo-500"
>
<!-- Glow layer: sits behind the label, only opacity animates -->
<span
aria-hidden="true"
class="absolute -inset-0.5 rounded-md bg-indigo-500 opacity-0 blur-md
transition-opacity duration-300 ease-out
group-hover:opacity-60 group-focus-visible:opacity-60
motion-reduce:transition-none"
></span>
<!-- Button surface: covers the glow, border brightens in sync -->
<span
class="relative flex items-center rounded-md border border-indigo-400/50 bg-indigo-600
px-7 py-3 text-sm font-medium text-white
transition-colors duration-300 ease-out
group-hover:border-indigo-300 group-focus-visible:border-indigo-300
motion-reduce:transition-none"
>
Hover me
</span>
</button>
CSS — styles.css
/* Glow Button — vanilla CSS */
.glow-button {
position: relative;
isolation: isolate;
display: inline-flex;
align-items: center;
padding: 0.75rem 1.75rem;
border: 1px solid rgb(129 140 248 / 0.5);
border-radius: 6px;
background-color: #4f46e5;
color: #ffffff;
font: 500 0.875rem / 1.25rem system-ui, sans-serif;
cursor: pointer;
transition: border-color 300ms ease-out;
}
/* Glow layer: blurred copy of the button, behind it, only opacity animates */
.glow-button::before {
content: "";
position: absolute;
inset: -2px;
z-index: -1;
border-radius: inherit;
background-color: #6366f1;
filter: blur(12px);
opacity: 0;
transition: opacity 300ms ease-out;
}
.glow-button:hover,
.glow-button:focus-visible {
border-color: #a5b4fc;
}
.glow-button:hover::before,
.glow-button:focus-visible::before {
opacity: 0.6;
}
.glow-button:focus-visible {
outline: 2px solid #6366f1;
outline-offset: 4px;
}
@media (prefers-reduced-motion: reduce) {
.glow-button,
.glow-button::before {
transition: none;
}
}
Adjacent