What do the values mean?
box-shadowtakes four numbers and a color: horizontal offset, vertical offset, blur radius, and spread. Blur softens the shadow's edge; spread grows or shrinks it. Giving spread a negative value is the most practical way to pull a shadow in under an element when you're also using a large blur. insetflips the shadow inward instead of outward — that's how recessed panels, pressed buttons, and inner borders are built. A shadow always follows the element's border-radius, and it never takes up layout space, so it never shifts the surrounding layout.
Why isn't a single layer enough?
In the real world, an object's shadow isn't a single flat shape: it's dark and sharp where the object touches the surface, and lighter and more spread out further away. That's why a single 0 10px 20px shadow looks artificial. For believable depth, use two or three layers: a small-offset, lightly blurred layer anchors the object to the surface, while a wide, faint layer suggests height. Layers are separated by commas, and the first layer in the list paints on top. The same trick works for focus rings: write 0 0 0 2px in the background color, then 0 0 0 5pxin the accent color, and you get a two-tone ring that doesn't disturb the border.
Performance and common mistakes
Very large blur radii force the browser to repaint a wide area on every frame; animating box-shadowdirectly on hover tends to stutter because of this. It's better to put the shadow on a ::after layer and animate only its opacity. If you're shadowing a transparent PNG or SVG and need the shadow to trace the actual shape, use filter: drop-shadow() instead of box-shadow— the former always follows the rectangular box, the latter follows the image's real silhouette. Writing the shadow in a dark, slightly saturated tint of the background color instead of pure black also makes the result look cleaner. Pairing edge softening with the border-radius tool makes this easier.