Also available in: Español · Português · Français · العربية
Box shadow generator
Layer shadows, copy the CSS, and see the number the blur radius is actually setting — and how far your shadow really reaches.
What is a box shadow generator?
It gives you sliders for the four numbers a CSS shadow takes — horizontal offset, vertical offset, blur radius and spread — plus a colour, and writes the declaration. Add more shadows and they stack, which is how the layered, soft shadows in modern interfaces are built.
This one also tells you what the blur radius means, because it does not mean what its name suggests. The panel under the preview turns your blur into the number the renderer is actually using, and into the distance your shadow will still be painting at.
Everything runs in your browser. Nothing is uploaded, and there is no account.
How to use the box shadow generator
- Set the four numbers. Offset moves the shadow, blur softens its edge, and spread grows or shrinks the shape before any blurring happens. A negative spread is how you get a tight shadow under a card without a halo around it.
- Add layers if you want depth. Real depth usually comes from two or three shadows at different blurs rather than one big one. Note that shadows are painted first on top, which is the reverse of how the list reads.
- Read the panel, then copy. It shows the Gaussian standard deviation your blur corresponds to, how far the shadow still paints, and the filter: blur() value that would look the same. The CSS block is ready to paste.
A blur radius of 20px is not 20px of blur
The CSS specification is specific about this, and almost no generator repeats it. In the section on blurring shadow edges, CSS Backgrounds and Borders Level 3 says the rendered shadow must approximate — with each pixel within 5% of its exact value — the image you would get by applying a Gaussian blur whose standard deviation is half the blur radius.
So `box-shadow: 0 0 20px` is a Gaussian with a standard deviation of 10. The blur radius is two sigma. That is not a detail if you also use filters, because `filter: blur(20px)` takes a standard deviation directly — the same number, the same word, and twice the softening. To reproduce a `filter: blur(N)` with a box-shadow you need a blur radius of 2N, which this tool checks as an exact identity at every distance rather than an approximation.
Two useful consequences fall out of the maths. Blurring a straight edge with a Gaussian gives an error function, and an error function passes through exactly one half at the step. So a blurred shadow sits at exactly 50% of its colour's alpha along the outline you drew, not at full strength. Half of the blur falls inside the shape and half outside, which is why turning the blur up never makes a shadow bigger — it makes the edge fuzzier and, at the edge, lighter. Growing a shadow is what spread is for, and the two get confused constantly.
The second consequence is the one that causes bugs. A Gaussian has tails, so a shadow does not stop at its blur radius. Working out where the alpha falls below one 8-bit step — the point past which nothing can be drawn at all — gives about 1.33 times the blur radius, in every direction, at every size. A 20px blur is still painting something 27px out. If a parent has overflow hidden and your shadow looks clipped despite the numbers seeming to fit, that ratio is why.
None of this makes a shadow look wrong; it makes it predictable. The reason to know the standard deviation is that it is the number every other blur in the stack is expressed in — SVG filters, canvas shadows, design tools — and box-shadow is the odd one out for doubling it.
Honest limitations
The preview is a real element with a real box-shadow, so what you see is your own browser drawing it. The figures in the panel are computed from the specification, not measured from the pixels: the spec allows a renderer 5% per pixel, so a browser is permitted to differ slightly from the ideal Gaussian and some do, particularly at very large radii where they approximate with repeated box blurs.
The analysis panel describes the first shadow in the list. With several layers the maths applies to each one separately and they composite, which is not something a single number can summarise honestly — so the tool does not pretend to.
Reach is computed for a straight edge. At a corner the shadow is the blur of a curved shape, so the falloff is slightly different, and for an inset shadow the whole geometry inverts. The straight-edge figure is the right one for the practical question — how much room does this need — and it is not exact at the corners.
This site's own design language bans shadows outright, and that has not changed: the preview swatch is the only shadow on this page, and the rest is flat by intent. The rule constrains our pages, not a tool built for other people's. It is worth saying that a shadow is often the wrong instrument anyway — a hairline border or a background tint carries the same hierarchy without the render cost or the halo.
The engine carries 40 assertions. Because JavaScript has no error function, one had to be written, and it is checked against Python's standard library across 1,207 points with a worst error under 1e-7 — plus a control confirming a plausible-looking wrong function fails that same bar. The harness runs the Python oracle itself rather than asking for a prior step, after the first version silently skipped that comparison on Windows because Git Bash and Node disagree about where /tmp is.
Why is it free?
Four sliders and an error function are work your own machine does instantly. Nothing is uploaded, there is no account, and there is nothing to watermark.
If you want corners rather than shadows, the border-radius generator on this site is next door — and it has a similar story about a spec rule nobody surfaces.