The parameters, and what each does
A box shadow takes horizontal and vertical offset, blur radius, spread radius and colour. Offsets place the shadow relative to the element; blur softens the edge, extending roughly half the blur radius beyond the shadow's boundary in each direction; spread grows or shrinks the shadow before blurring, which is useful for tightening a glow or creating an outline.
The inset keyword flips the shadow inward, which is how pressed states, inner glows and inset borders are built. An inset shadow with zero offset and a small blur produces a subtle recess that reads as depth without any change in layout.
Text shadows take the same parameters minus spread, and multiple shadows are comma-separated on both properties. Shadows are painted in order with the first on top, which matters when layering.
Making shadows look real
The single biggest improvement is to use several layered shadows instead of one. Real shadows are not uniform: they are darkest and tightest near the object and become progressively softer and fainter further away. Stacking three or four shadows with increasing offset and blur, each at lower opacity, approximates that falloff and looks dramatically better than one large blur.
Pick a consistent light source and keep it across the whole interface. Convention is light from above, so shadows fall downward with a positive vertical offset and little or no horizontal offset. An interface where different components imply different light directions looks subtly wrong even to people who cannot identify why.
Use colour rather than black. Pure black at low opacity reads as grey and desaturates whatever is beneath it, whereas a shadow tinted toward the background hue — or a darker, more saturated version of the surface colour — looks far more natural. On coloured backgrounds this is the difference between a shadow that sits in the design and one that looks pasted on.
Performance and dark mode
Large blur radii are expensive. Shadow rendering cost scales with the blurred area, so a full-width element with a 100 px blur is genuinely costly, and animating blur radius forces a repaint every frame. If a shadow must animate, animate opacity on a pre-rendered shadow layer instead, which the compositor can handle without repainting.
box-shadow follows the element's border box and its border radius, but not the shape of its content. For an irregular shape or a transparent PNG, filter: drop-shadow() is the right property — it follows the alpha channel, which is why it works on icons and cut-out images where box-shadow would draw a rectangle.
Dark interfaces need a different approach entirely. A dark shadow on a dark background is nearly invisible, so depth is conveyed by making elevated surfaces lighter rather than by casting shadows — the approach Material Design formalised with elevation overlays. A subtle light border on the top edge, suggesting a highlight rather than a shadow, is often more effective than any shadow at all.