20 CSS Animated Buttons01 / 20

Pure CSSMIT licensed

CSS Neon Glow Button

A neon-lit CTA button with a pulsing glow halo and colour-shifting outline, built entirely with CSS box-shadow animations and no JavaScript.

Published

Live Demo
Try it

The code

<div class="ab-01">
  <div class="ab-01__scene">
    <p class="ab-01__label">Premium SaaS — Launch Your Project</p>
    <h2 class="ab-01__headline">Build faster.<br>Ship smarter.</h2>
    <p class="ab-01__sub">Join 50,000+ developers already on the platform.</p>
    <button class="ab-01__btn">Get Started Free</button>
    <p class="ab-01__hint">No credit card required · Cancel anytime</p>
  </div>
</div>
.ab-01,
.ab-01 *,
.ab-01 *::before,
.ab-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ab-01 ::selection {
  background: #b829ff;
  color: #fff;
}

.ab-01 {
  --neon: #b829ff;
  --neon-dim: rgba(184,41,255,.35);
  --bg: #0a0010;
  --text: #e8d5ff;
  font-family: system-ui,sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ab-01__scene {
  text-align: center;
  padding: 2.5rem 2rem;
  max-width: 520px;
}

.ab-01__label {
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--neon);
  margin-bottom: .75rem;
  opacity: .8;
}

.ab-01__headline {
  font-size: clamp(1.8rem,4vw,2.6rem);
  font-weight: 800;
  color: #fff;
  line-height: 1.15;
  margin-bottom: .75rem;
}

.ab-01__sub {
  font-size: .95rem;
  color: var(--text);
  opacity: .7;
  margin-bottom: 2rem;
}

.ab-01__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .85rem 2.4rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: #fff;
  background: transparent;
  border: 2px solid var(--neon);
  border-radius: 8px;
  cursor: pointer;
  outline: none;
  text-transform: uppercase;
  transition: color .3s,background .3s,border-color .3s,box-shadow .3s;
  box-shadow: 0 0 8px var(--neon-dim),0 0 20px var(--neon-dim),inset 0 0 10px rgba(184,41,255,.08);
  animation: ab-01-pulse 2s ease-in-out infinite;
  will-change: box-shadow;
  text-shadow: 0 0 8px rgba(184,41,255,.6);
}

.ab-01__btn:hover {
  background: var(--neon);
  color: #fff;
  box-shadow: 0 0 16px var(--neon),0 0 40px var(--neon),0 0 80px var(--neon-dim),inset 0 0 16px rgba(255,255,255,.15);
  text-shadow: none;
  animation-play-state: paused;
}

.ab-01__btn:active {
  transform: scale(.97);
}

@keyframes ab-01-pulse {
  0%,
    100% {
    box-shadow: 0 0 8px var(--neon-dim),0 0 20px var(--neon-dim),inset 0 0 10px rgba(184,41,255,.08);
  }

  50% {
    box-shadow: 0 0 14px var(--neon),0 0 36px var(--neon-dim),0 0 60px rgba(184,41,255,.15),inset 0 0 16px rgba(184,41,255,.12);
  }
}

.ab-01__hint {
  margin-top: 1rem;
  font-size: .78rem;
  color: var(--text);
  opacity: .45;
}

@media (prefers-reduced-motion: reduce) {
  .ab-01__btn {
    animation: none;
  }
}
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 Animated 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: CSS Neon Glow Button
Source: https://codefronts.com/motion/css-animated-buttons/css-neon-glow-button/

A neon-lit CTA button with a pulsing glow halo and colour-shifting outline, built entirely with CSS box-shadow animations and no JavaScript.
## HTML
```html
<div class="ab-01">
  <div class="ab-01__scene">
    <p class="ab-01__label">Premium SaaS — Launch Your Project</p>
    <h2 class="ab-01__headline">Build faster.<br>Ship smarter.</h2>
    <p class="ab-01__sub">Join 50,000+ developers already on the platform.</p>
    <button class="ab-01__btn">Get Started Free</button>
    <p class="ab-01__hint">No credit card required · Cancel anytime</p>
  </div>
</div>
```
## CSS
```css
.ab-01,
.ab-01 *,
.ab-01 *::before,
.ab-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ab-01 ::selection {
  background: #b829ff;
  color: #fff;
}

.ab-01 {
  --neon: #b829ff;
  --neon-dim: rgba(184,41,255,.35);
  --bg: #0a0010;
  --text: #e8d5ff;
  font-family: system-ui,sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ab-01__scene {
  text-align: center;
  padding: 2.5rem 2rem;
  max-width: 520px;
}

.ab-01__label {
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--neon);
  margin-bottom: .75rem;
  opacity: .8;
}

.ab-01__headline {
  font-size: clamp(1.8rem,4vw,2.6rem);
  font-weight: 800;
  color: #fff;
  line-height: 1.15;
  margin-bottom: .75rem;
}

.ab-01__sub {
  font-size: .95rem;
  color: var(--text);
  opacity: .7;
  margin-bottom: 2rem;
}

.ab-01__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .85rem 2.4rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: #fff;
  background: transparent;
  border: 2px solid var(--neon);
  border-radius: 8px;
  cursor: pointer;
  outline: none;
  text-transform: uppercase;
  transition: color .3s,background .3s,border-color .3s,box-shadow .3s;
  box-shadow: 0 0 8px var(--neon-dim),0 0 20px var(--neon-dim),inset 0 0 10px rgba(184,41,255,.08);
  animation: ab-01-pulse 2s ease-in-out infinite;
  will-change: box-shadow;
  text-shadow: 0 0 8px rgba(184,41,255,.6);
}

.ab-01__btn:hover {
  background: var(--neon);
  color: #fff;
  box-shadow: 0 0 16px var(--neon),0 0 40px var(--neon),0 0 80px var(--neon-dim),inset 0 0 16px rgba(255,255,255,.15);
  text-shadow: none;
  animation-play-state: paused;
}

.ab-01__btn:active {
  transform: scale(.97);
}

@keyframes ab-01-pulse {
  0%,
    100% {
    box-shadow: 0 0 8px var(--neon-dim),0 0 20px var(--neon-dim),inset 0 0 10px rgba(184,41,255,.08);
  }

  50% {
    box-shadow: 0 0 14px var(--neon),0 0 36px var(--neon-dim),0 0 60px rgba(184,41,255,.15),inset 0 0 16px rgba(184,41,255,.12);
  }
}

.ab-01__hint {
  margin-top: 1rem;
  font-size: .78rem;
  color: var(--text);
  opacity: .45;
}

@media (prefers-reduced-motion: reduce) {
  .ab-01__btn {
    animation: none;
  }
}
```

How this works

The glow effect layers multiple box-shadow values on the button — an inset layer for inner luminance plus two outer rings with different blur radii. A @keyframes ab-01-pulse animation oscillates the shadow spread and opacity on a 2 s loop, giving the halo a breathing quality without touching the DOM. The outline is a transparent border that transitions to the accent colour on :hover, creating the classic neon tube look purely via CSS property transitions.

The text colour itself rides a subtle text-shadow transition so the label appears to emit light. will-change: box-shadow promotes the element to its own composite layer, keeping the animation smooth at 60 fps even alongside other page content. The prefers-reduced-motion media query pauses the pulse but preserves the hover glow for accessibility.

Make it yours

  • Change the glow colour by updating --neon (default #b829ff) — the box-shadow, border, and text-shadow all derive from this one variable.
  • Control pulse speed by editing animation-duration on .ab-01__btn (try 1s for urgency or 4s for ambient mood).
  • Add a second colour stop by duplicating the keyframe and interpolating to a second --neon-alt variable for a colour-cycling halo.
  • Increase glow size for hero placements by multiplying the box-shadow blur values (e.g. change 20px to 40px on the outer ring).
  • Remove the inner glow for a subtler look by deleting the inset 0 0 … shadow layer and keeping only the outer rings.

Gotchas — read before shipping

  • Very large box-shadow blur values (> 60px) can trigger sub-pixel painting jitter on Chrome/Windows with certain GPU drivers — test on target hardware.
  • Safari < 15.4 paints box-shadow changes on the main thread; combine with transform: translateZ(0) to force GPU compositing.
  • The pulsing halo adds to the stacking context — if the button is inside a position: relative container with overflow: hidden the outer glow will be clipped.

Browser support

ChromeSafariFirefoxEdge
69+12+62+69+

All features are broadly supported; only extreme blur values vary between GPU drivers.

Techniques used in this demo

Search CodeFronts

Loading…