← Back to gallery
CSS

Neon Glow Layering with Text Shadow

A layered text-shadow stack — crisp white core + colored halo + wide outer bloom. Only opacity animates so the flicker reads electrical, not pulsing. Three flicker programs: a steady warm hum, a cyan signal pulse, and a violet stutter.

neon-flickerglowtext-shadowlayered-shadowopacity-flickerprefers-reduced-motion

Neon flicker · text-shadow stack

Neon Glow Layering Text Shadow

Multiple text-shadow radii build a crisp neon core, a colored halo, and a slower outer bloom without replacing the live text node. Three variants demonstrate a cyan-magenta street sign, an amber utility tube, and a quiet blue ambient glow.

Cyan core · magenta halo

Street Sign

A classic street-sign neon — most of the cycle reads bright, with a brief irregular dim flicker around 40% as if the tube has a loose connection. The cyan core stays bright; only the magenta outer halo dims.

  • street sign
  • irregular dim
  • broken-neon vibe

Amber tube · short spark

Console Warning

A utility status indicator — regular ON/OFF pulse cadence like a status LED on a server rack. The amber core punches bright, dims to half, punches again. Predictable rhythm signals "system live".

  • status LED
  • rhythmic pulse
  • utility

Soft blue · no hard dropout

Quiet Glow

A slow ambient glow that breathes rather than flickers — no steps, no broken-electrical feel. Good for headers where the neon language fits but rapid flicker would compete with navigation.

  • ambient
  • breathing
  • no steps

Neon inspector

Street Sign

  • street sign
  • irregular dim
  • broken-neon vibe

A classic street-sign neon — most of the cycle reads bright, with a brief irregular dim flicker around 40% as if the tube has a loose connection. The cyan core stays bright; only the magenta outer halo dims.

Helped you ship something? 🐟 Send my cat a churu

.neon-word {
  display: inline-block;
  color: #f0fdff;
  font-weight: 800;
  letter-spacing: 0.06em;
  /* Layered shadow stack: tight white core → mid-blur accent halo →
     wide outer accent-2 bloom. The shadow stack is static; only the
     opacity animates so the flicker reads as electrical, not as the
     halo growing/shrinking. */
  text-shadow:
    0 0 2px currentColor,
    0 0 8px #22d3ee,
    0 0 18px #f472b6,
    0 0 30px #22d3ee;
  animation: neon-sign 2.50s steps(20, end) infinite;
}

@keyframes neon-sign {
  /* Mostly bright — brief unstable dim ~38-44% (loose-tube feel). */
  0%, 36%, 46%, 100% { opacity: 1; }
  38%, 44% { opacity: 0.55; }
}

@media (prefers-reduced-motion: reduce) {
  .neon-word { animation: none; }
}

How to make this

A neon glow text effect stacks several text-shadow radii for a crisp core, colored halo, and outer bloom, then flickers opacity without changing layout.

html
1<p class="neon-glow-recipe">  <span class="neon-glow-recipe__word">OPEN LATE</span></p> <style>.neon-glow-recipe {  margin: 0;  padding: 1rem;  border-radius: 16px;  background: #020617;  text-align: center;}13.neon-glow-recipe__word {  display: inline-block;  max-inline-size: 100%;16  color: #f0fdff;  font: 800 clamp(1.6rem, 8vw, 3.4rem)/1 ui-sans-serif, system-ui;  letter-spacing: .08em;  white-space: nowrap;  text-shadow:21    0 0 2px currentColor,    0 0 8px #22d3ee,    0 0 18px #f472b6,    0 0 30px #22d3ee;  animation: neon-glow-recipe-flicker 2.5s steps(20, end) infinite;}27@keyframes neon-glow-recipe-flicker {  0%, 36%, 46%, 100% { opacity: 1; }29  38%, 44% { opacity: .55; }}31@media (prefers-reduced-motion: reduce) {  .neon-glow-recipe__word { animation: none; }}@media (forced-colors: active) {  .neon-glow-recipe__word {    color: CanvasText;    text-shadow: none;  }}</style>

Annotated snippet

  1. Line 1Keep the word as live text. The glow is paint styling, not an image replacement, so selection, zoom, and screen readers keep the original text.
    PitfallWhich browsers support layered text-shadow?

    Layered text-shadow is broadly supported in modern browsers. Forced-colors and high-contrast modes may suppress decorative glow, so the base text color must still have enough contrast.

  2. Line 13Large display text needs stable sizing before glow is added. Do not use viewport-only sizing that can make the word overflow on narrow screens.
    PitfallAre layered text-shadows performant?

    A few shadows on one heading are usually fine. Many large blurred shadows across lists or animated every frame can increase paint cost, especially on low-end mobile devices.

  3. Line 16The shadow stack works from tight to wide: a crisp readable core, a colored mid halo, then a softer outer bloom.

    Same word, same color, same font, same opacity flicker. Only the text-shadow value differs. A single 0 0 28px blur spreads the entire glow at one radius — the result is a muddy cyan halo and the letterforms lose their crisp edges. The layered stack (2px crisp core, 8px cyan halo, 18px magenta mid, 30px cyan bloom) builds the glow from tight to wide so the letterforms keep a readable core while the bloom radiates outward.

    PitfallWhy not use one huge text-shadow for neon text?

    A single large blur makes the letterforms muddy. Stack small, medium, and large shadows so the text keeps a crisp readable core while the outer layers create the glow.

  4. Line 21Only opacity flickers. The glow geometry stays static, so the sign feels electrical without the halo expanding and contracting.

    Same layered shadow stack at rest (2/8/18/30 px blur, cyan + magenta). Animating the four blur radii smoothly between the full stack and a tight stack (1/3/6/10 px) makes the halo visibly inflate and deflate — the glow continuously breathes, reading as a slow-pulse lamp rather than neon. Animating opacity over the same static stack with sharp steps cuts the whole sign between full brightness and 35 % twice in a row — the halo shape never moves, but the intensity snaps off and on, exactly how a fluorescent tube glitches.

    PitfallShould I animate text-shadow blur radii?

    Usually avoid it for neon flicker. Animating opacity over a static shadow stack is cheaper and reads more like an electrical cut. If you animate blur, keep the range small.

  5. Line 27steps() creates a hard neon cut instead of a smooth breathing fade. Use it sparingly and keep the bright state dominant.
    PitfallShould I animate text-shadow blur radii?

    Usually avoid it for neon flicker. Animating opacity over a static shadow stack is cheaper and reads more like an electrical cut. If you animate blur, keep the range small.

  6. Line 29The dim frames never hit opacity zero. The text remains readable during the flicker instead of becoming a flashing disappearance.
    PitfallCan neon flicker be an accessibility problem?

    Yes. Avoid rapid high-contrast flashing, never make the text fully disappear, and honor prefers-reduced-motion by freezing the flicker. Important text should remain readable without the animation.

  7. Line 31Reduced motion disables the flicker but leaves the same glow stack applied. The visual identity remains without repeated blinking.
    PitfallCan neon flicker be an accessibility problem?

    Yes. Avoid rapid high-contrast flashing, never make the text fully disappear, and honor prefers-reduced-motion by freezing the flicker. Important text should remain readable without the animation.

Advanced

Layer a breathing halo on top of the electrical flicker

Same crisp letterforms, same flicker. BEFORE keeps the text-shadow stack at fixed radii — the glow buzzes (opacity flicker) but the bloom stays a constant size. AFTER layers a second keyframe that animates the shadow blur radii through a slower 3.6s ease-in-out cycle, so the bloom inhales and exhales while the flicker handles the rapid buzz. Two animations, two different rhythms, one sign that feels alive.

View explanation and full code25 lines

The base recipe handles the electrical buzz with an opacity-only flicker (cheap, no layout cost). Real neon signs also breathe — the bloom slowly inhales and exhales over a longer cycle, independent of the rapid flicker bursts. Animate the text-shadow blur radii in a second keyframe on a 3.6s ease-in-out loop and layer it onto the same selector. Two animations run independently: the flicker handles short dimming bursts; the breathing keyframe handles the long-cycle bloom pulse.

Append these rules inside the <style> block from the base snippet above.

css
/* Advanced: breathing halo — extends the base recipe. */.neon-glow-recipe__word {  animation:    neon-glow-recipe-flicker 2.5s steps(20, end) infinite,    neon-glow-recipe-breathe 3.6s ease-in-out infinite;}@keyframes neon-glow-recipe-breathe {  0%, 100% {    text-shadow:      0 0 2px currentColor,      0 0 8px #22d3ee,      0 0 18px #f472b6,      0 0 30px #22d3ee;  }  50% {    text-shadow:      0 0 2px currentColor,      0 0 12px #22d3ee,      0 0 28px #f472b6,      0 0 48px #22d3ee;  }}@media (prefers-reduced-motion: reduce) {  .neon-glow-recipe__word { animation: none; }}

Notes

Overview

Neon glow effects stack multiple text-shadow layers — a crisp white core, a colored halo, and a wide outer bloom — with only the opacity (or none of the layers) animating so the flicker reads as electrical, not pulsing. Three programs ship: a steady warm hum, a cyan signal pulse, and a violet stutter.

When to use it

Reach for neon glow on retro signage, hero headlines, gaming surfaces, and any product that wants a tactile light source rather than flat depth. Skip it on dense or pale backgrounds — the glow disappears against light surfaces and looks garish against busy ones. Skip it for accessibility-critical text where the flicker can compromise legibility.

How it works

The shadow stack is a comma-separated text-shadow with three or four progressively wider blur radii — 0 0 2px white, 0 0 8px var(--accent), 0 0 24px var(--accent), 0 0 56px var(--bloom). The tightest layer sits at the glyph edge as the “core”; the widest layer is the ambient bloom. The flicker animation targets opacity on the whole text node (or on a wrapper) so all layers attenuate together — animating individual blur radii instead would feel like the glow is pulsing rather than the lamp flickering.

Production gotchas

Multiple wide blur radii on text are expensive on lower-end mobile GPUs; cap the largest blur under 64px or the cost compounds across many neon elements. The flicker keyframe should jump between high and low opacity (not smoothly interpolate) for real neon character — use animation-timing-function: steps(2, end) or sharp keyframes for the on/off transitions. Layered shadows do not clip to padding or borders, so a neon button needs padding larger than the largest blur radius or the glow extends past the click target visibly.

Accessibility

Flicker rates above 3Hz can trigger photosensitive epilepsy — never set the flicker keyframe shorter than 333ms. Under prefers-reduced-motion: reduce pin the opacity at full so the neon stays steady — the static glow still communicates the “lit” aesthetic without any motion. Verify text contrast at minimum opacity for every glow color.

References

Implementation depth

Neon glow is a stack of small and large text-shadow layers, not one huge blur. The inner layer keeps the glyph edge sharp while outer layers create the sign-like halo.

Flicker should be rare and low amplitude. Constant opacity changes are tiring and can reduce contrast, so reduced motion should disable flicker and leave a stable glow that still meets readability expectations.