Text Shadow Generator
Build layered text shadows visually and copy the CSS
Click a layer to edit it; earlier layers paint on top in the CSS output.
Text shadows are one of the cheapest ways to add depth, glow, or readability to headings without images or filters. This generator lets you build shadows layer by layer, tune offsets, blur, color, and opacity against live light and dark previews, then copy a clean text-shadow declaration. Five presets cover the effects most people reach for, and every layer is reorderable so you can control exactly what paints on top.
How to Use
- Pick a starting point. Choose Subtle, Hard Outline, Neon Glow, Retro 3D, or Emboss to load a tuned stack, or keep the default single soft shadow.
- Select a layer. Click any row in the layer list; the selected row is outlined and its values load into the editor.
- Tune it. Move the offset X, offset Y, and blur sliders (or type exact numbers), then set the color and opacity.
- Stack and reorder. Add layers for more depth, then use the arrows to move a layer up or down. The order is the painting order.
- Check both themes. Switch between the light and dark preview backgrounds and drag the font-size slider from 24px to 96px.
- Copy. The output is a ready-to-paste
text-shadow: ...;declaration.
The Painting-Order Rule
The single most important thing to understand about text-shadow is that earlier layers sit on top. In the Neon Glow preset, layer 1 is 0px 0px 4px — a tight, bright core — and layer 4 is 0px 0px 56px, a wide, faint halo. If you reversed them, the wide halo would sit over the core and wash it out. The same logic drives the Retro 3D preset, where progressively darker copies step one pixel further down and right; the lightest copy is listed first and stays visible on top.
Offsets are measured from the text’s original position: a positive x moves the shadow right, a positive y moves it down. A zero offset with a positive blur produces a glow centred on the glyphs, while a small positive y with a modest blur gives the classic raised-letter look. Blur controls how far the color bleeds outward; at zero the shadow is a hard-edged duplicate exactly the size of the glyphs. Opacity is tracked separately from the color’s own alpha because the picker emits opaque hex, and the generator converts it to rgba() for you. If you hand-edit the result, keep the units: text-shadow: 0 2px 4px #000 is valid, but text-shadow: 0 2 4 black is not.
The Five Presets, Decoded
| Preset | Layers | What it produces |
|---|---|---|
| Subtle | 1 | 0px 2px 4px black at 25% — a soft drop shadow for body or headings |
| Hard Outline | 4 | Zero-blur black copies at -1/0, +1/0, 0/-1, 0/+1 px — a legible outline |
| Neon Glow | 4 | Same cyan at 4, 12, 28, and 56 px blur, opacity stepped 90→60% |
| Retro 3D | 5 | Dark red copies stepped 1–5 px down-right, zero blur |
| Emboss | 2 | White at 0 -1px above plus a faint dark line at 0 1px 1px below |
Start from the closest preset and adjust rather than building from an empty stack. For a soft UI shadow, the Subtle preset at 25% is already close; raise the y offset toward 4–6px and the blur to 8–12px for more lift. For an outline that stays readable over a photo, use Hard Outline and set the color to a dark tint of the background rather than pure black. For a glow, keep the offsets at zero and vary only blur and opacity, and keep the color saturated — desaturated glow colors read as fog. The Retro 3D stack is the one preset where changing the color to your brand palette matters most, since its five layers should step from light to dark in even increments.
Worked Example: Reading the Output
Loading Neon Glow produces this exact declaration:
text-shadow: 0px 0px 4px rgba(15, 240, 252, 0.9), 0px 0px 12px rgba(15, 240, 252, 0.8), 0px 0px 28px rgba(15, 240, 252, 0.7), 0px 0px 56px rgba(15, 240, 252, 0.6);
Load Hard Outline instead and the zero-blur layers drop the blur component, yielding -1px 0px #000000, 1px 0px #000000, 0px -1px #000000, 0px 1px #000000. The default layer is 0px 2px 4px rgba(0, 0, 0, 0.3), and raising its opacity to 100% switches the color to plain #000000.
Edge Cases and Limits
- Multiple shadows are expensive. Each layer is an extra pass over every glyph, so a five-layer shadow on a long paragraph costs noticeably more than one on a short heading. Keep heavy stacks for display text.
- Blur is capped at 100px and offsets at ±50px. Values typed outside those ranges are clamped, not rejected.
- Color input is limited to hex. The picker emits
#rrggbb; the logic normalizes three- or six-digit hex and falls back to#000000for anything invalid. - No spread and no inset. If you need to shadow the element’s box rather than its letters, this is the wrong property and the wrong tool.
- Contrast still matters. A shadow can make text harder to read; verify the result over the real background, not just the preview swatches.
- Large blurs smear small text. A wide dark shadow behind small light text reduces contrast rather than improving it, so test at the smallest size you will actually ship.
- The preview shows one line of text. Long strings that wrap may reveal layering or overlap issues the single-line sample hides, so sanity-check in your own markup.
Related Tools
- CSS Box Shadow Generator — Design layered box shadows with live preview.
- CSS Flexbox Generator — Design flexbox layouts visually and copy the CSS.
- CSS Gradient Generator — Build custom CSS gradients for your layouts.
Frequently Asked Questions
Why is there no spread radius or inset option like box-shadow has?
Because CSS text-shadow does not support them. The text-shadow property accepts only an x offset, a y offset, an optional blur radius, and a color per layer; unlike box-shadow, it has no spread value and no inset keyword, and it never accepts a negative blur. The generator sticks to what the browser will actually render, so anything you copy is valid CSS.
Which layer gets painted on top when I stack several?
The first layer in the comma-separated list is painted last, so it appears on top of the layers after it. That is why the Neon Glow preset lists its tight 4px blur first and its wide 56px halo last — the bright core sits above the faint spread. Use the up and down arrows to reorder layers and watch the preview update immediately.
How does opacity end up in the CSS output?
A layer at 100% opacity is emitted as a plain hex color such as #000000. Any value below 100% is converted to rgba(), for example #0ff0fc at 90% becomes rgba(15, 240, 252, 0.9). The alpha is rounded to two decimal places, so small nudges of the slider produce clean, readable output rather than long float values.
What happens if I delete every layer?
The generator never leaves you with an empty stack. Removing the final layer immediately inserts a fresh default layer (0px 2px 4px at 30% black opacity), so the preview and the copied CSS always contain at least one valid shadow. The default is also what you start with on page load.
Can I export the shadow with a selector or class, or only the property?
The output panel gives you the declaration only: text-shadow: ...; with the layers comma-joined in stacking order. Paste it inside whichever rule you like — a heading class, a button, or a utility layer — and add your own selector. Zero-blur layers are written without a blur component, so the output stays as short as the effect allows.
Do the 24px to 96px font-size preview and the light/dark toggle affect my CSS?
No, both are preview-only controls. Changing the font size or switching the background just re-renders the sample text, because the same shadow can look dramatic at 96px on dark and nearly invisible at 24px on white. Your copied text-shadow value never includes font size or background — those belong to the element you apply it to.
Reviewed by the HandyTools Hub team · Last updated