How box-shadow works
The box-shadow property draws one or more shadows around an element's box.
Each shadow is written in this order:
box-shadow: [inset] offset-x offset-y [blur] [spread] color;
- Horizontal and vertical offset: how far the shadow moves right and down. Negative values move it left or up.
- Blur: the larger it is, the softer the edge. With
0the shadow has a hard edge. - Spread: grows or shrinks the shadow before blurring it. A negative value tucks it under the element.
- Colour: almost always black or the background colour at low opacity, for example
rgba(0, 0, 0, 0.2). inset: the shadow goes inside the element, as if it were pressed in.
Multiple shadows on one element
Shadows are separated by commas and the first one sits on top. Combining a short, crisp shadow with a wide, soft one looks far more natural than a single dark shadow: that is what the Raised and Layered presets do.
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.08),
0 8px 24px rgba(0, 0, 0, 0.12);
Shadows on images: box-shadow or drop-shadow
box-shadow follows the shape of the box, including its border-radius, so it is what you
need for photos and cards. If the image is a PNG or SVG with a transparent background and you want the shadow
to follow the outline of the drawing, use the drop-shadow() filter:
img.logo { filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3)); }
drop-shadow() has no spread or inset, and does not take comma-separated layers.
Tips
- Keep opacity low (between 0.05 and 0.25): a black shadow at 50% rarely looks good.
- For a shadow only at the bottom, combine a vertical offset with negative spread:
0 8px 6px -6px. - Shadows barely show in dark mode: a subtle border or a slightly lighter background works better.
- To animate a shadow, animate the
opacityof a pseudo-element that carries it, notbox-shadowitself: it is much smoother.