Skip to content
ColorKit

Free CSS text-shadow builder

Text shadow generator that previews real type, not a box

Type is the only fair preview for a text shadow, so this generator renders your own words at the size, weight and tracking you will ship them at — free, no signup, up to 24 layers. Nine presets cover what people actually build with the property: outlines at four and at eight offsets, letterpress, emboss, a four-stage neon glow, a six-step retro 3-D, a sixteen-step long shadow, and the two-layer scrim that keeps white headings readable over a photograph. Three gradient backdrops stand in for that photograph, and against a flat color the panel scores the pair to WCAG 2.1 at the size on screen.

  • 100% free
  • No signup
  • 9 effect presets
  • Type from 12 to 160px
  • Up to 24 layers

Readable at any size

Typeface
Behind the type

A ratio cannot be computed against an uneven backdrop — WCAG measures one pair of flat colors, and the shadow itself counts for nothing in that measurement.

Effects

Shadow layers — the last one is furthest back

  • 10px 1px 2px rgba(0, 0, 0, 0.9)
  • 20px 2px 12px rgba(0, 0, 0, 0.55)

CSS

text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9), 0px 2px 12px rgba(0, 0, 0, 0.55);

2 of 24 layers · 14px of blur in total · 78 characters, repainted on every scroll frame the type moves

If you only wanted an outline, stroke it instead

-webkit-text-stroke: 1px #000000;
paint-order: stroke fill;
text-shadow: none;

One declaration instead of eight layers, and paint-order keeps the stroke outside the glyph rather than eating half its weight.

Press Ctrl+V anywhere on the page to drop in the headline you are really shipping, so the preview shows your words — no need to click the field first.

How to generate a text shadow

Three steps, in the order that stops you tuning a shadow for the wrong type size.

  1. Set the type before you set the shadow

    Type your own words into the sample field, then choose the size, weight, tracking and typeface you are actually going to ship. This order matters more here than anywhere else in CSS: a 2px blur that reads as a soft lift under a 96px display line closes up the counters of a 16px paragraph and turns it to mud, so a shadow judged at the wrong size is judged wrong.

  2. Put something difficult behind it

    Switch the backdrop between a flat color you pick and three gradient scenes — a bright warm one, a cool one and a low-key night one. Shadows exist for the uneven case, so tuning one over flat white proves nothing. With the flat color selected the panel also scores your type against it to WCAG 2.1, using the preview's own size and weight to decide whether the threshold is 4.5:1 or 3:1.

  3. Load an effect, then take it apart

    Each of the nine presets fills the layer list: an outline is four or eight zero-blur offsets around the glyph, a neon glow is four concentric blurs at 4, 9, 20 and 40px in your own type color, retro 3-D is six solid one-pixel steps with a soft drop beneath. Every layer then unfolds into offset-x, offset-y, blur and alpha, and Copy CSS hands you the finished declaration.

Technical specifications

Values per layerThree lengths — offset-x, offset-y and blur radius — plus a color. No spread, no inset; those belong to box-shadow only
Layers per declarationUp to 24 comma-separated shadows. The long-shadow preset uses 16 of them on its own, one per diagonal step
Slider rangesOffsets −40 to +40px, blur 0 to 60px, alpha 0-100% in 1% steps
Preview type12-160px, weight 100 to 900 in steps of 100, tracking from −60 to +200 thousandths of an em, over four device-resident stacks: system sans, Georgia, monospace and a condensed display face
Backdrops4 — one flat color of your choosing plus three CSS gradient scenes, warm, cool and low-key, built from radial gradients so nothing is fetched from another host
Contrast readingAgainst the flat backdrop only: WCAG 2.1 relative luminance, with the 3:1 large-text threshold applied automatically at 24px or at 18.66px when the weight is 700 or more
Presets9 — outline at 4 and at 8 offsets, photo scrim, letterpress, emboss, neon glow, retro 3-D, 16-step long shadow and a hard drop
Stroke alternative-webkit-text-stroke with paint-order: stroke fill, still prefixed but honoured by Chrome, Edge, Safari and Firefox 49 and later

Frequently asked questions

Does text-shadow have a spread radius?

No — the property takes at most three lengths, and they are offset-x, offset-y and blur radius in that order. Copying a four-length value across from box-shadow is the single most common way to make an entire declaration invalid, and the browser drops the whole thing silently rather than the one bad layer. There is no inset keyword either: a shadow cast inward on a glyph is not something the property can express.

Why does my shadow make 16px body text look dirty?

Because at that size the blur is spilling into the counters — the enclosed white shapes inside a, e and o — and filling them in. Body copy tolerates roughly a 1px offset and a 1px blur at most; anything beyond that is legible only above about 24px. If a paragraph genuinely needs help standing off its background, the fix is almost always a semi-transparent plate behind the block rather than a shadow on each glyph.

How do I draw an outline around text?

Two ways, and the second is usually better. The shadow way stacks zero-blur copies of the glyph at ±1px: four of them covers the corners, eight of them adds the edges and looks smoother on curves and diagonals. The stroke way is -webkit-text-stroke: 1px with paint-order: stroke fill, which is one declaration instead of eight layers — the paint-order part is what keeps the stroke on the outside of the glyph rather than eating half the stem weight, and without it a 1px stroke reads as a thinner typeface.

Does a shadow help my text pass a contrast check?

It does not count for anything. WCAG 2.1 success criterion 1.4.3 compares the relative luminance of the text color against the background color behind it, and a shadow is neither of those two values, so the ratio you owe is unchanged whatever you stack around the glyph. A shadow does help a real human read white type over a photograph, which is why it is worth doing anyway — but score the underlying pair on its own and treat the shadow as a bonus for readers rather than as a credit against the criterion.

Can I put a shadow on a color emoji or an icon font?

On an icon font yes, on a color emoji not usefully. Icon fonts are ordinary monochrome glyphs, so the shadow traces the icon exactly. Color emoji are bitmap or COLR layers, and text-shadow paints from the glyph's alpha coverage, so you get a solid silhouette of the whole emoji in the shadow color sitting behind it. When that is not what you want, filter: drop-shadow reads the actual pixels and produces a shadow of the emoji's shape.

Do text shadows animate cleanly between two states?

Yes — shadow lists interpolate layer by layer, and if the two states have different layer counts the shorter list is padded with transparent zero-offset shadows, so a two-layer resting state can transition to a five-layer hover state without snapping. What it costs is a repaint of the text on every frame, which is noticeable on a long heading; fading a duplicate absolutely-positioned copy of the heading is cheaper when the animation runs during a scroll.

Why does the same value look heavier on Windows than on a Mac?

Different glyph rasterization, not a different shadow. macOS renders text with heavier stem weights and grayscale antialiasing, while Windows applies subpixel positioning and hinting that thins the same face, so a 1px dark shadow that sits behind a Mac glyph peeks out from under the thinner Windows one. Check any hairline effect — letterpress and emboss especially — at 100% zoom on both before shipping it.

About shadows on glyphs, and why legibility is the real job

The property has an odd history for something this ordinary. It appeared in CSS2, was pulled out of CSS2.1 because nobody had implemented it properly, and came back in CSS Text Decoration Level 3, which is where its current definition lives. Its shape reflects that: a comma-separated list where each entry is at most three lengths and a color, painted behind the glyph, with the first entry in the list nearest the front. There is no spread and no inset — the two extras box-shadow carries — and no way to clip or reshape the result, because what the shadow traces is the alpha coverage of the glyph itself rather than any box around it.

Nearly all serious use of it is one of three jobs. Making type readable over an image is the first and by far the commonest: a tight dark layer at high opacity to define the edge, and a wider soft one at half that to darken the region the glyph sits in. Faking a stroke is the second, done by stacking zero-blur copies at four or eight offsets, and it is the job the property is worst at — the outline frays on curves, eight layers cost eight paints, and -webkit-text-stroke with paint-order: stroke fill does it in one declaration. Decoration is the third, where letterpress, emboss and retro 3-D all work by placing hairline layers in opposing directions so the eye reads a light source; those are the effects that need checking at 100% zoom on more than one operating system, because a one-pixel layer either shows or does not depending on how the glyph was rasterized.

Two things other generators get wrong are worth naming. They preview the shadow on a fixed sample at one size, usually large, which hides the fact that the same numbers destroy body copy — the counters fill in long before the effect stops looking good on a heading. And they imply, or let you assume, that a dark halo fixes a contrast failure; it does not, because the ratio is computed from two flat colors and a shadow is neither of them, so the honest check is still the one in the color contrast checker. The backdrops here are built from layered radial gradients rather than photographs, so if you want to test against your own scene, compose it in the gradient generator or write it out with the CSS gradient generator. For the surface the type is sitting on rather than the type itself — a card, a button, a toast — the four-length property with spread and inset is the box shadow generator, and when the shadow needs to follow artwork instead of glyphs, drop-shadow in the CSS filter generator is the property that reads alpha.

Where your sample text stays

Every number on this page is worked out by JavaScript running in the tab you are reading it in. Nothing you type, paste or open is uploaded, logged or kept, which is also why the tools carry on working after you disconnect from the network.

The headline you type or paste into the sample field never leaves the component that renders it. Nothing is stored between visits, so a reload brings back the placeholder rather than your unreleased campaign line.