Box Shadow Generator_

A single blurred shadow is the reason so many interfaces look like paper cut-outs. Light in a room does not cast one shadow — it casts a tight dark one where the object nearly touches the surface and wider, fainter ones spreading out behind it, and the eye reads the difference immediately even when it cannot name it.

So this generator starts from a stack. Add layers, drag each one separately, and watch the preview against white, grey, dark and a photograph, because a shadow that looks convincing on white often disappears on everything else. Paste a value you already have and it comes apart into editable layers.

toolkit.codes/box-shadow-generator
Surface
Start from

UTF-8
Ready
100% LOCAL
Input
Any number of layers, each with its own offsets, blur, spread, colour and inset flag — or an existing box-shadow value pasted in and taken apart.
Output
A box-shadow declaration, written on one line for a single layer and one line per layer for a stack, in the order the browser paints them.
Processing
Applied to a real element in this tab, so what you see is the browser's own rendering rather than a drawing of it.
Limits
Shadow shape follows the element's border-radius, which is fixed here at a rounded rectangle. Colours are emitted as rgba; a value pasted in keeps whatever notation it arrived with.
Why the first layer is listed last in the CSS
Box-shadow paints the first layer on top and each later one beneath it, which is the opposite of how a stack of elements works and catches people out constantly. If a tight dark shadow vanishes behind a soft one, the two are the wrong way round in the list.

One shadow reads as fake

What a real shadow actually looks like

Hold a card a centimetre above a desk and there is a hard, dark line directly beneath its edge where almost no light reaches. Lift it to ten centimetres and that line softens into a broad grey smear. Both exist at once on any object with thickness: contact shadow at the bottom, ambient shadow spreading out around it. A single box-shadow can be one or the other and never both, which is why cards with one soft blur look like stickers pasted onto the page — they have the ambient shadow of something far away and the crisp edge of something touching.

Every design system that looks right ships a stack

This is not a matter of taste that the good ones happened to get right. Material Design's elevation levels are three shadows each — a tight umbra, a mid penumbra and a wide ambient. Tailwind's shadow utilities are two layers from shadow-sm upward. Apple's and GitHub's card treatments are stacked too. The reason is the same in every case: one blur radius cannot describe both the near and the far behaviour of light, so the systems that care use two or three and let the eye assemble them.

Negative spread is what separates the layers

Stack two shadows with the same spread and you get one thicker shadow, not two. The trick every good stack uses is a negative spread on the wider layers: 0 12px 20px -6px shrinks the shadow before blurring it, so the soft outer glow stays behind the object rather than bulging out past the tight one. Positive spread does the reverse and is mostly useful on its own — a zero-blur, positive-spread shadow is a border that takes up no layout space and can sit outside the element's box.

Shadows take no space, ever

Unlike a border, a box-shadow is painted outside the border box and contributes nothing to layout. Adding one never widens an element, never pushes a neighbour and never reflows a page — which is exactly why swapping a 1px border for a zero-blur shadow fixes the jump you get when adding a border on hover. The corollary is that a shadow will happily overlap whatever sits next to it, and no amount of margin on the shadow itself will stop it, because the shadow has no margin.

Opaque black is the other common mistake

A shadow is an absence of light, so it should darken whatever is beneath it rather than sit on top of it as a grey shape. #888 looks acceptable on white and looks obviously wrong the moment the surface behind it is coloured, textured or dark. Transparent black — rgba(0, 0, 0, 0.12) and the like — adapts to every background automatically. Better still on coloured surfaces is a shadow tinted toward the background's own hue rather than pure black, which is what makes shadows on a blue page look like shadows instead of dirt.

Build the stack, then copy it

  1. 01Start from a preset. Each one is the shape a real design system ships, and the number after its name is how many layers it uses.
  2. 02Adjust one layer at a time. The first row paints on top; later rows paint beneath it.
  3. 03Give the wider layers a negative spread so they stay behind the tight one instead of bulging past it.
  4. 04Check it against the dark and photo surfaces. A shadow that only works on white is using an opaque colour, and the note beneath the controls will say so.
  5. 05Copy the CSS. A single layer is emitted on one line; a stack gets one line per layer, in paint order.

A card that looks placed rather than pasted

The single blur is the default everywhere and it is the reason the card looks like it was cut out and glued down.

The usual
box-shadow: 0 4px 8px rgba(0,0,0,.2);
Contact plus ambient
box-shadow:
  0 1px 3px rgba(0,0,0,.1),
  0 4px 8px -1px rgba(0,0,0,.1);

A border that does not move anything

Adding a 1px border on hover shifts the element by a pixel and nudges its neighbours. A zero-blur shadow does not, because shadows are outside layout entirely.

Jumps on hover
border: 1px solid #ddd;
Does not
box-shadow: 0 0 0 1px rgba(0,0,0,.15);

A focus ring that follows the corners

A ring drawn with spread rather than outline traces the element's border-radius exactly, and stacking two gives the white gap that keeps it legible on any background.

What you want
visible on light and dark,
rounded like the button
Two layers do it
box-shadow:
  0 0 0 2px #fff,
  0 0 0 4px rgba(37,99,235,.6);

A value from devtools you want to tune

Most visits to a shadow generator start with a value already in hand — copied out of an inspector or exported by a design tool — and wanting to nudge it, not rebuild it.

Pasted in
0 1px 2px rgba(0,0,0,.06),
0 8px 16px -4px rgba(0,0,0,.1)
What happens
Two editable layers, sliders set
to the values it arrived with.

The four lengths, and what each one changes

PartExampleWhat it does
Offset X0Moves the shadow horizontally. Almost always zero in interface work, because the implied light source is directly overhead.
Offset Y4pxMoves it down. This is what reads as height — the further the shadow falls, the further the object seems to be from the surface.
Blur8pxHow soft the edge is. Roughly twice the offset is a good starting ratio; much less looks hard, much more looks like fog.
Spread-2pxGrows or shrinks the shadow before blurring. Negative spread is what keeps stacked layers separate; positive spread with zero blur is a border.
Colourrgba(0,0,0,.12)Almost always transparent black. An opaque grey sits on the background instead of darkening it.
insetinset 0 2px 4px …Paints the shadow inside the border box instead of outside — a well rather than a rise. Inputs and pressed buttons use it.

Order matters within a layer: the lengths are always X, Y, blur, spread, and the keyword inset may appear at either end but nowhere in the middle.

Getting shadows right

  • Keep offset X at zero unless you have a reason. Interface light comes from above, and a sideways shadow makes one card disagree with every other card on the page.
  • Raise the offset and the blur together as an element rises, and lower the opacity as you do. Distant shadows are larger and fainter, not larger and darker.
  • Tint shadows toward the surface behind them on coloured backgrounds. Pure black over a saturated colour reads as grime rather than shade.
  • Use one elevation scale across a project instead of tuning shadows per component. Three or four defined levels are what make a set of surfaces feel like one system.
  • Prefer transform and opacity for hover animations. Animating box-shadow repaints every frame; cross-fading two stacked elements, or animating a shadow already present at opacity zero, does not.

Where box shadows go wrong

The layers paint in the opposite order from what you expect

The first shadow in the list is drawn on top and every later one goes beneath it. Put the wide soft layer first and it will cover the tight dark one completely, which looks like the tight layer simply having no effect.

A large blur costs paint time on every frame

Big soft shadows are expensive to rasterise, and the cost is paid again whenever anything on the page animates or scrolls. A long list of cards each carrying a 60px blur is a common and well-hidden cause of jank on mid-range phones.

Inset shadows do not stack the way outer ones do

An inset shadow is clipped to the padding box, so a second inset layer beneath the first is largely hidden by it. Inset is usually one layer, and mixing inset and outer shadows on the same element rarely reads as anything coherent.

The shadow follows border-radius, not the visible shape

It traces the border box exactly. An element whose apparent shape comes from a background image, a clip-path or a child that overflows will cast a shadow of the rectangle underneath, which is why clip-path and box-shadow do not combine — use filter: drop-shadow for those, since it follows the alpha channel instead.

Syntax, painting and cost

Syntax
Two to four lengths, an optional colour and an optional inset keyword, with layers separated by commas. Omitting the colour makes the shadow inherit the element's current colour, which is rarely what anyone intends.
Paint order
First layer on top, each subsequent layer behind it. The reverse of stacking contexts, and the single most common surprise in the property.
Layout
None. Shadows are painted outside the border box and take no space, so they cannot push a neighbour and cannot be pushed by one.
Shape
Follows the border box and its border-radius. For an arbitrary silhouette, filter: drop-shadow respects the alpha channel instead — at a higher cost, and with only one shadow per filter function.
Animation
Animatable, and expensive. Layers interpolate one to one only when both values have the same number of them; otherwise the browser falls back to a discrete swap.
Support
Unprefixed everywhere since IE9. The multi-layer form and negative spread are equally old, so a stack needs no fallback.
Network
None from tool code. A test sweep calls every function this page uses with fetch and XMLHttpRequest replaced by stubs that throw, so a stray request fails the build instead of shipping. Disconnect from the network and the page still works.

Questions about CSS box shadows

How do I create a box shadow in CSS?

box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); — horizontal offset, vertical offset, blur radius and colour. Spread is an optional fourth length, and adding a second comma-separated layer is what turns a flat blur into something that looks like real depth.

Why does my box shadow look flat or fake?

Almost always because it is one layer. Real light casts a tight dark shadow where an object nearly touches a surface and a wider faint one spreading beyond it, and a single blur radius can only be one of the two. Add a second layer with a larger offset, a larger blur and a negative spread.

What does the spread value do?

It grows or shrinks the shadow before the blur is applied. Negative spread pulls a wide soft layer back behind a tighter one, which is what keeps stacked shadows from merging into a single smear. Positive spread with zero blur produces a solid ring — a border that occupies no layout space.

How do I add multiple shadows to one element?

Separate them with commas: box-shadow: 0 1px 2px rgba(0,0,0,.1), 0 8px 16px -4px rgba(0,0,0,.1). There is no practical limit, though past three or four layers another one stops being visible while still costing paint time.

Which shadow layer appears on top?

The first one in the list. Each subsequent layer is painted behind it, which is the opposite of how stacked elements behave. If a small sharp shadow seems to have no effect, it is probably listed after a large soft one that is covering it.

What is the difference between box-shadow and drop-shadow?

box-shadow follows the border box and its corner radius, so it always casts a rounded rectangle. filter: drop-shadow follows the element's alpha channel, so it traces a transparent PNG, an SVG icon or a clip-path correctly. drop-shadow costs more and takes only one shadow per function, though several functions can be chained.

Do box shadows affect layout?

Never. They are painted outside the border box and contribute nothing to width, height or flow, so adding one cannot move anything on the page. This is why replacing a hover border with a zero-blur shadow removes the one-pixel jump that borders cause.

Are box shadows bad for performance?

Large blurs are. The shadow has to be rasterised, and that work repeats whenever the element is repainted — during scrolling or animation, on every frame. Small shadows are inexpensive; a long list of cards with 60px blurs on a mid-range phone is not.

How do I make an inner shadow?

Prefix the value with the inset keyword: box-shadow: inset 0 2px 4px rgba(0,0,0,.12). The shadow is then painted inside the padding box, which reads as a recess. Inset layers are clipped, so stacking several of them achieves much less than stacking outer ones does.

Is anything I build here uploaded?

No. The work is JavaScript running in this tab. Every function it calls is covered by a test that stubs fetch and XMLHttpRequest to throw, so a request that slipped in would break the build rather than reach a server — and you can confirm it for yourself by disconnecting and carrying on.