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.

featured articles

popular favourites

Wall textureRobbie the Robot with a transperant background
Robby the robot

Creating a True Cross-Browser Drop Shadow Effect With CSS3 & SVG

Recently I discussed the drop-shadow filter, which is newly supported in Webkit. Firefox users saw the same effect in the article, even though the browser doesn’t yet support CSS3 filters.

That’s due to the fact that Firefox supports the older SVG version of the filter, from which the CSS3 version is derived. In this article I’m going to show you how to write the effect for all browsers*, so you can achieve the benefits of a true, dynamic drop shadow for all elements.

Webkit

The CSS3 Webkit version first, as a refresher:

  1. -webkit-filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5));

The syntax is very straightforward: the values for the filter represent, in order, horizontal offset, vertical offset, blur and the color of the shadow (given as an rgba value to create a realistic shadow against any background).

Firefox

Now the SVG version. You can either save this as a separate file (shadow.svg) or embed it on a web page. The code is as follows:

  1. <svg height="0" xmlns="http://www.w3.org/2000/svg">
  2. <filter id="drop-shadow">
  3. <feGaussianBlur in="SourceAlpha" stdDeviation="2.2"/>
  4. <feOffset dx="12" dy="12" result="offsetblur"/>
  5. <feFlood flood-color="rgba(0,0,0,0.5)"/>
  6. <feComposite in2="offsetblur" operator="in"/>
  7. <feMerge>
  8. <feMergeNode/>
  9. <feMergeNode in="SourceGraphic"/>
  10. </feMerge>
  11. </filter>
  12. </svg>

The SVG syntax is considerably more complex, and I’m not going to explain all of it here. The good news is that you only need to alter four values: stdDeviation is the amount of blur; dx is the horizontal offset and dy the vertical, with flood-color being the color of the shadow.

IE

Finally, the equivalent for Internet Explorer:

  1. /* for IE 8 & 9 */
  2. -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12,
  3. Color='#444')";
  4. /* For IE 5.5 - 7 */
  5. filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12,
  6. Color='#444')";

You’ll find that the visual quality is not nearly as good in IE – and you do have to do some re-jiggering and testing to translate the CSS3/SVG values into legacy DX filters – but the dropshadow will appear at least appear in Internet Explorer.

Bringing It All Together

I’d suggest combining all these approaches as a class, as you’d usually want to apply the effect to more than one element on the same page… and naturally, you’d want all of the shadows on the page to fall in the same direction, to ensure a consistent visual appearance:

  1. .shadowed {
  2. -webkit-filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5));
  3. filter: url(shadow.svg#drop-shadow);
  4. -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12,
  5. Color='#444')";
  6. filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12,
  7. Color='#444')";
  8. }

(If you embedded the SVG code directly on the page, you’d use just the id value: note that it matches the id on the SVG code sample).

That’s it! You can now apply the class to a transparent PNG or any other element to gain a true drop-shadow effect across modern browsers.

*Opera is the exception here: it neither supports SVG filters on external content nor the native CSS3 filters, at least as of this writing.

You must be signed up in order to leave comments.

eh, sorry for the above comment- i shouldnt have bothered pasting in my code. to reiterate, the effect seems to fail on Safari and IE9 and im hoping you can help me figure out what i may be doing wrong. here is a JSFiddle with my code: http://jsfiddle.net/mroncetwice/LtZ4E/

posted by mroncetwice

im seeing it work in Chrome and FF, but not IE(9) nor in Safari. my code is below ... any idea what i may be doing wrong?

.shadowed {
-webkit-filter: drop-shadow(0px 1px 2px rgba(0,0,0,0.42));
filter: url(#drop-shadow);
-ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=1, 
Color='#000')";
filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=1, 
Color='#000')";
}

posted by mroncetwice

Dudley StoreyHi MrOnce: I've tested the code you've presented here (cleaned up and formatted for the next version of the blog, coming in a few weeks) in Safari 6 (I don't have IE available at the moment) and it works fine. I'm curious as to what version of Safari you're using?

posted by Dudley Storey

ah, i see that Safari is no longer being updated for Windows (im using the latest Windows version of Safari, 5.1.7), so that explains that issue. please do let me know if you get a chance to check out my JSFiddle in IE (9 or below)

posted by mroncetwice

web developer guide

featured comment

by Aisling Brock in New Business Card Design

what i'm reading

A Feast for Crows: A Song of Ice and Fire: Book Four
A Feast for Crows: A Song of Ice and Fire: Book Four

what i'm watching

Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]
Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]

what i'm playing

Borderlands
Borderlands

what i'm hearing

Planets
Planets

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.