elefcode
← All guides

Design · 4 min read

CSS box-shadow Explained: Realistic, Layered Shadows

Shadows give interfaces depth and show what can be clicked or lifted. The default single dark shadow often looks harsh — a few techniques make them look like real light.

Try it yourself with the related tool.

Design a box-shadow →

Advertisement

The five values

box-shadow: 0 4px 12px -2px rgb(0 0 0 / 0.15) reads as horizontal offset, vertical offset, blur radius, spread, and colour. Positive offsets move the shadow right and down. Blur softens the edge; a negative spread shrinks the shadow so it hides under the element instead of peeking out of the sides.

Layer shadows for realism

Real objects cast a tight, darker shadow close to them and a wide, faint one further away. Comma-separate two or three shadows with increasing offset and blur and decreasing opacity, for example a 1px shadow plus a 4px plus a 16px one. The result looks soft and natural rather than like a grey smudge.

Keep the light source consistent across the page — if one card's shadow falls down, they all should.

Colour and dark mode

Pure black shadows can look dirty on coloured backgrounds; a dark, low-opacity tint of the background hue looks better. On dark backgrounds shadows barely show, so use lighter surface colours or a subtle border to show elevation instead.

Inset shadows and performance

The inset keyword draws the shadow inside the box, which suits pressed buttons and input fields. Animating box-shadow repaints on every frame; for smooth hover effects, animate the opacity of a pseudo-element that carries the larger shadow instead.

Related guides