box-shadow quite literally makes a box. shadow. That means it always casts a rectangle, no matter the shape of your element. I find quite fascinating though the functions that CSS provide, which allow you to make more interesting stuff. filter is one of them. A drop shadow filter is a (optionally) blurred, offset version of the input image’s alpha mask, drawn in a specific color and composited below the image.
box-shadow
drop-shadow()
The example shows a star shadow implemented with the two alternative ways.
The box-shadow property creates a rectangular shadow behind an element’s entire box, while the drop-shadow() filter function creates a shadow that conforms to the shape (alpha channel) of the image itself.
/* box-shadow — shadow is always rectangular */
.icon { box-shadow: 4px 4px 8px black; }
/* drop-shadow — shadow follows the actual shape */
.icon { filter: drop-shadow(4px 4px 8px black); }
This makes all the difference for PNGs with transparency, SVGs, and cut-out shapes.
filter: drop-shadow(<offset-x> <offset-y> <blur> <color>);
The color property can set as first or last, it doesn’t matter. Blur defaults to 0 if omitted.
filter: drop-shadow(4px 4px 8px crimson);
filter: drop-shadow(crimson 4px 4px 8px); /* same thing */
filter: drop-shadow(4px 4px); /* sharp shadow, uses currentColor */
drop-shadow(10px 10px)
drop-shadow(-10px -10px)
drop-shadow(10px 10px crimson)
drop-shadow(10px 10px 10px crimson)
drop-shadow(1px 1px) drop-shadow(1px -1px) drop-shadow(-1px 1px) drop-shadow(-1px -1px)
you can chain drop-shadow() calls inside a single filter to layer shadows:
filter:
drop-shadow(1px 1px 0 navy)
drop-shadow(-1px -1px 0 navy);
⚠️ Unlike box-shadow, there is no inset or spread parameter.