Drop shadows. Web designers have loved them for a long time to the extent that we used to fake them with PNG images before CSS Level 3 formally introduced them to the spec as the
box-shadow property. I still reach for drop shadows often in my work because they add a nice texture in some contexts, like working with largely flat designs.
Not too long after
box-shadow was introduced, a working draft for CSS Filters surfaced and, with it, a method for
drop-shadow() that looks a lot like
box-shadow at first glance. However, the two are different and it’s worth comparing those differences.
For me, the primary difference came to light early on when I started working with
box-shadow. Here’s a simple triangle not unlike the one I made back then.
Let’s use this to break down the difference between the two.
box-shadow on that bad boy and this happens.
It’s annoying, but makes sense. CSS uses a box model, where the element’s edges are bound in the shape of a rectangle. Even in cases where the shape of the element does not appear to be a box, the box is still there and that is was
box-shadow is applied to. This was my “ah-ha moment” when understanding the box in
CSS Filters are pretty awesome. Take a gander at all the possibilities for adding visual filters on elements and marvel at how CSS suddenly starts doing a lot of things we used to have to mockup in Photoshop.
Filters are not bound to the box model. That means the outline of our triangle is recognized and the transparency around it is ignored so that the intended shape receives the shadow.
The answer is totally up to you. The simple example of a triangle above might make it seem that
filter: drop-shadow() is better, but it’s not a fair comparison of the benefits or even the possibilities of both methods. It’s merely an illustration of their different behaviors in a specific context.
Like most things in development, the answer of which method to use depends. Here’s a side-by-side comparison to help distinguish the two and when it might be best to choose one over the other.
|Box Shadow||Drop Shadow|
|Specification||CSS Backgrounds and Borders Module Level 3||Filter Effects Module Level 1|
|Supports Spread Radius||Yes, as an optional fourth value||No|
|Blur Radius||Calculation is based on a pixel length||Calculation is based on the
|Performance||Not hardware accelerated||Hardware accelerated in browsers that support it. It’s a heavy lift without it.|
The difference between
filter: drop-shadow() really boils down to the CSS box model. One sees it and the other disregards it. There are other differences that distinguish the two in terms of browser support, performance and such, but the way the two treat the box model is the key difference.
Update: Amelia identified another key difference in the comments where the spread of the radius for
drop-shadow()is calculated differently than
box-shadowand even that of
text-shadow. That means that the spread radius you might specify in
box-shadowis not one-to-one with the default spread value for
drop-shadow, so the two are not equal replacements of one another in some cases.