demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Comparison of drop-shadow filter (left) to box-shadow property (right) on a 16-bit alpha-masked PNG image. Illustration by Aria Lance).

box-shadow property vs. drop-shadow filter: a complete comparison

css / shadows

Estimated reading time: 4 minutes, 37 seconds

There’s been a lot of talk over the last few days over the differences between the CSS3 box-shadow property and the drop-shadow filter. * The former has been around for a long time, and is well-supported across modern browsers; the latter is a translation from SVG into CSS, and currently only has support in recent Webkit-based applications, or in Firefox through an equivalent SVG filter.  At first glance the CSS and filter shadow techniques appear to be same effect: even their syntaxes are very similar. As we’ll see, there are some very significant differences between the two.

.shadowCSS { box-shadow: 12px 12px 7px rgba(0,0,0,0.5); }
.shadowfilter { -webkit-filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5));
filter: url(shadow.svg#drop-shadow); }

Much of the recent conversation has focused on one feature or another; this article will be a complete side-by-side matchup of the two systems, comparing flexibility, rendering speed and quality. You will need a recent Webkit browser (Safari 6+, Chrome 18+) or Firefox to see the filter version.

Photograph of a woman in a cat mask
border-image:url(gold-picture-frame.png) 81 83 82 84;
border-width: 60px;
filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3));
filter: url(shadow.svg#drop-shadow);

The most exciting part of filter shadows is that they follow the explicit outline of elements. That’s even true for 32 and 16-bit PNG’s, as you can see above. box-shadow (as the name implies) reflects the rectangular shape of the image, ignoring the alpha mask; filter shadow follows the mask outline of the PNG.

That also includes border-images, as shown in the photograph above (provided by Stefano Corso under Creative Commons), provided the border-image is an alpha-masked PNG.

The drop-shadow filter takes into account the addition of pseudo-elements, such as :before and :after, as in these pure-CSS speech-bubbles: note the shadow underneath the triangle in the filtered version.

“A girl’s gotta eat.”

filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3)); filter: url(shadow.svg#drop-shadow);

“It’s such a waste when pretty things get broken.”

box-shadow: 9px 9px 7px rgba(0,0,0,0.3);

Limitations of the drop-shadow filter

A few drawbacks of the filter approach should be noted at this point:

  • The dropshadow filter should support a fourth spread value to swell the shadow just as box-shadow does, but it appears that the current implementation in Webkit will consider a fourth value a parsing error and turn off the shadow entirely in response.

  • The filter spec does not support an inset value, so you can't easily create inner shadows with filter code.

Further differences

Both shadow effects respect border-radius and transform, but the filtered shadow will appear “under” an element with no background, whereas box-shadow will treat it as solid. If the border is irregular (dashed, for example), the filter will honor that; box-shadow will not.

border: 3px solid #262b57; width: 150px; height:150px;
border-radius: 10px; transform: rotate(8deg);
box-shadow: 9px 9px 7px rgba(0,0,0,0.3);
filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3));
filter: url(shadow.svg#drop-shadow);
border: 3px dashed #262b57;
box-shadow: 9px 9px 7px rgba(0,0,0,0.3);
filter: drop-shadow(9px 9px 9px rgba(0,0,0,0.3));
filter: url(shadow.svg#drop-shadow);

Because it is only shadowing the border (which is just four pixels thick in this case) the filter version appears lighter.

Judgement

filter(box-shadow) is definitely the winner in this round: it has far greater flexibility, and only loses when it comes to inset shadows and (current) lack of spread.

Speed & Quality

While the rendering quality appears much the same between the two systems, drop-shadow filters have the advantage of hardware acceleration if the browser vendor supports it; box-shadow does not have access to that code. All other factors being equal, the drop-shadow filter will tend to render faster.

Conclusion

So which do you use? At this stage I think we can set a few simple rules:

  1. if your element is solid and has a solid border (with or without border-radius), use box-shadow. It has better support, and will provide the same visual result as the drop-shadow filter, albeit a few milliseconds slower.

  2. If you want an inset shadow – for example, to achieve a vignette effect – use box-shadow.

  3. If you have a PNG image with an alpha mask, there are several options:

    1. Bake in the shadow using or your image editor of choice, so that every browser sees it the same way;

    2. Leave the image unaltered and use the drop-shadow filter, knowing that only Webkit browsers will see the shadow for now.

    3. Try to use an SVG drop-shadow filter on the content for equivalency in other browsers.

If your element has an irregular outline that’s not controlled by border-radius - why not take advantage of CSS fallback techniques and use both?

“Show a man what he expects to see, and he won’t look beneath the surface.”

One cautionary note is that both shadow render systems will be active with this CSS: Webkit will “double up” the shadow on the regular element. However, you will achieve fallback support in older browsers that only have box-shadow.

I’m also going to place a bet that the filter version will be open to manipulation by CSS3 Custom Filters… which will be great for doing curved drop-shadows without any need for trickery.

As you can see, the two systems are very different, and appropriately named: hopefully this comparison can be a metric for you to decide how to use either in your future projects.

*Although I should point out that Lea Verou was, as ever, on top of this subject almost a year ago.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.