EmpireUI
Get Pro
← Blog7 min read#text-shadow#css#glow effect

CSS text-shadow: Glow Effects, Neon Text and Layered Shadows

Master CSS text-shadow from basics to layered neon glow effects. Learn the exact syntax, stacking tricks, and animation patterns that make text pop.

Neon glowing text effect on a dark background showcasing CSS shadows

The text-shadow Property: What It Actually Does

The syntax is dead simple: text-shadow: offset-x offset-y blur-radius color. Four values. That's it. But what you can do with those four values — and more importantly, with a comma-separated list of them — is where things get genuinely interesting.

Introduced in CSS2 and then quietly dropped, text-shadow came back in CSS3 (around 2009–2010) and hasn't changed since. No vendor prefixes needed. Full browser support across everything you'd actually ship to in 2026.

The offset values push the shadow horizontally and vertically. A blur radius of 0 gives you a hard clone of the text shape — useful for that chunky layered look you see in neobrutalism designs. Crank the blur up to 20px and you've got a soft glow. The color can be any valid CSS color, including rgba() and hsl() — and yes, you want rgba() when layering.

One more thing — the property doesn't affect layout at all. The shadow can bleed outside the element's bounding box without triggering overflow or pushing other elements around. That makes it much more predictable than box-shadow in tight layouts.

Layered Shadows: Stacking Multiple Values

This is where text-shadow gets powerful. You can stack as many shadow layers as you want, separated by commas. The first value in the list renders on top, the last renders at the bottom.

Honestly, most developers stop at one shadow and miss the whole point. A single text-shadow usually looks flat or unconvincing. Three to five layers, each slightly different in blur and opacity, is what gives that convincing depth or glow.

Here's a straightforward layered drop shadow that works well on light backgrounds: ``css .layered-shadow { color: #1a1a2e; text-shadow: 2px 2px 0px #c8c8d0, 4px 4px 0px #b0b0bc, 6px 6px 0px #9898a8, 8px 8px 0px rgba(0,0,0,0.15); } `` Each layer shifts 2px further down-right and gets slightly darker. The result is a stacked 3D extrusion effect without any JavaScript or SVG filters.

Worth noting: performance-wise, each shadow layer is an extra paint operation. Four or five layers is fine. Thirty is not. Keep it reasonable or your GPU will have opinions.

Neon Glow Text: The Classic Technique

Neon glow is probably the most-requested text-shadow effect. It shows up everywhere from cyberpunk UIs to synthwave dashboards. The trick is layering the same color at progressively larger blur radii.

You want at least three layers: a tight 0px spread for the core brightness, a medium blur for the inner glow, and a wide blur (think 20px or beyond) for the outer halo. Using rgba() at lower opacity on the outer layers keeps the effect from looking like a mistake.

``css .neon-text { color: #fff; text-shadow: 0 0 4px #fff, 0 0 10px #fff, 0 0 20px #e040fb, 0 0 40px #e040fb, 0 0 80px #e040fb; } ` Swap #e040fb for any saturated hue. Cyan (#00e5ff), hot pink (#ff006e), acid green (#39ff14`) — all read well on near-black backgrounds. You'll find a bunch of color combinations worth stealing from the glassmorphism components section on Empire UI.

Look, the neon effect only works on dark backgrounds. On white or light grey, the wide blur just dissolves. If you need it on a light UI, either invert your logic (dark text with a very subtle warm shadow) or add a dark text container behind the glow element.

Animating text-shadow for Pulsing Glow

Static glow is nice. Animated glow is better. CSS @keyframes and animation pair with text-shadow cleanly — you can tween between two or more shadow states.

The key is keeping the number of shadow layers the same in both keyframes. Browsers interpolate each layer independently, so if you have five layers in 0% and three in 100%, the animation snaps instead of blending.

``css @keyframes neon-pulse { 0%, 100% { text-shadow: 0 0 4px #fff, 0 0 10px #fff, 0 0 20px #e040fb, 0 0 40px #e040fb; } 50% { text-shadow: 0 0 2px #fff, 0 0 6px #fff, 0 0 10px #e040fb, 0 0 20px #e040fb; } } .neon-pulse { animation: neon-pulse 2s ease-in-out infinite; } ` This halves the blur radius at the midpoint, simulating a flicker. Fast version at 0.3s for an anxious strobe; slow 3s` for a calm ambient breathe.

That said, be careful with animation: infinite on anything the user stares at for a long time. WCAG 2.1 AA requires a way to pause animations that run for more than 5 seconds. Wrap it in a prefers-reduced-motion query: ``css @media (prefers-reduced-motion: reduce) { .neon-pulse { animation: none; } } ``

Retro and Vaporwave Text Effects

Beyond neon, text-shadow is also the backbone of several retro aesthetics. The vaporwave and y2k styles lean heavily on offset hard shadows and chromatic aberration illusions.

A chromatic aberration effect uses offset red and cyan (or red and blue) shadows with zero blur, shifted only a few pixels apart. It looks like a misaligned CRT screen and reads instantly as retro-digital: ``css .chroma-text { color: #fff; text-shadow: -3px 0 2px rgba(255, 0, 80, 0.7), 3px 0 2px rgba(0, 200, 255, 0.7); } ` Keep the offset under 6px or it gets unreadable fast. Around 2px4px` is the sweet spot.

Quick aside: the long shadow trend from 2013-era flat design is also pure text-shadow. You stack 60–80 layers at 1px diagonal increments, same color at low opacity. It's tedious to hand-write — use a Sass loop or a PostCSS plugin for it.

If you're already exploring these aesthetics across your whole UI, the gradient generator and box shadow generator tools on Empire UI are worth bookmarking. They let you iterate on color combinations visually before you write a single line of CSS.

text-shadow vs filter: drop-shadow — Know the Difference

People confuse these two constantly. text-shadow only applies to the text glyphs themselves. filter: drop-shadow() applies to the rendered element including any transparent regions — so if your element has a background, the shadow follows the element box, not just the letters.

For pure text effects, text-shadow is almost always what you want. It's also cheaper to composite. filter: drop-shadow() runs through the browser's filter pipeline, which triggers a new stacking context and can cause stutter on complex pages when animated.

In practice, the one case where filter: drop-shadow() wins over text-shadow is SVG text or text inside a clip-path. text-shadow won't follow a clipped shape, but drop-shadow will. Outside that narrow use case, stick with text-shadow.

Does browser support matter here? Not really — both properties have been solid since Chrome 18 and Firefox 35. You're not going to hit a compatibility wall in 2026 with either one.

Practical Tips and Common Mistakes

A few things that'll save you debugging time. First: text-shadow doesn't accept spread-radius. That's box-shadow only. If you paste a box-shadow value into text-shadow, the browser will silently ignore the whole declaration. The property takes offset-x offset-y blur color — no spread.

Second, color order matters more than you'd think. If you put a wide blurry shadow before a tight sharp one, the sharp detail gets painted on top — which is usually what you want for glow. Reverse the order and the fine detail disappears under the blur.

Third, test on actual dark screens. OLED displays make glow effects look completely different from an IPS panel at full brightness. What looks like a subtle 4px glow at your desk can look almost invisible on a dimmed phone in a dark room. Go wider than you think you need.

One more thing — text-shadow is inherited. If you set it on a parent element, every child text node picks it up unless you explicitly reset it with text-shadow: none. That bites people constantly when they set a glow on a heading container and wonder why their paragraphs are glowing too.

FAQ

How many text-shadow layers can I use before it affects performance?

There's no hard limit, but beyond 8–10 layers you'll notice paint performance drop on mobile, especially when animating. For static effects, 5 layers is plenty for convincing depth or glow.

Can I use text-shadow with CSS custom properties (variables)?

Yes, fully. You can put the entire shadow value in a variable or just individual parts like color or blur radius. Custom properties inside text-shadow interpolate correctly in transitions too.

Does text-shadow work on SVG text elements?

Partially — it works in most browsers on SVG <text> elements, but support is inconsistent. For SVG text, filter: drop-shadow() is the more reliable choice.

Why does my glow effect look washed out on light backgrounds?

Glow effects depend on contrast against a dark background. On light backgrounds the wide blur radius just blends into the page. Either switch to a dark container or use a tight offset shadow instead of a radial glow.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

CSS Box Shadow: The Complete Guide With Live ExamplesCSS border-radius Patterns: From Rounded to Blob ShapesNeon Glow Effect in CSS: text-shadow, box-shadow and filter StacksCyberpunk Button Design in CSS: Neon Glow, Glitch and Clip-Path