Friday, August 14, 2009

Using CSS3 box-shadow with IE

At YayArt, we show a lot of images. An important part of the presentation is subtle drop shadows.

My original solution to that problem was a Javascript hack that inserts a couple of 1 pixel wide divs at the edge of any element with a shadow class. However, although I have tweaked it several times, it has always been a bit slow. For instance, for the shop front page we're currently rendering more than 60 elements with shadows which takes a couple of seconds with Firefox and Firebug on my old trusty PIII 950 MHz laptop. I'll note that this is actually an order of magnitude faster than the (more general) code I based it on from somewhere else. The really tricky part was decent-speed IE 6 support because that actually required measuring the DOM elements.

However, Firefox 3.5 was released about a month ago, and one of the good news was support for the box-shadow CSS3 property. It's a relatively simple property for adding drop shadows. So given that Safari has it, and has had for some time, and most Firefox users will soon have it, it starts getting interesting. For reference, about half of our visitors are Firefox + Safari (+ Chrome which uses the same rendering engine as Safari).

If you search for box-shadow, some are already using it to add a bit of extra embellishment. However, on YayArt, it's an integrated part of the design. So I had to figure out how to make it work on all browsers.

I ended up with a three-way solution. For recent Firefox/Safari/... I use box-shadow. For non-box-shadow supporting browsers, I fallback to the old hack. And for Internet Explorer, I'm using a new hack based on the proprietary filter stuff in IE.

Here's a quick sketch. I put this in the general stylesheet:
.shadowed {
-moz-box-shadow: 2px 2px 3px #969696;
-webkit-box-shadow: 2px 2px 3px #969696;
}
This makes it work with browsers based on the Gecko and Webkit engines. Some people recommend adding a plain box-shadow line, but I need full control over which browsers are responding, and besides it seems to defeat the purpose of the browsers using the -engine- prefix. Here's a demo:

If your browser is recent enough, you can see a shadow here.

Now for the fallback, I need to discover in Javascript whether the browser is using the CSS:
function supportsBoxShadow() {
var s = document.body.style;
return s.WebkitBoxShadow !== undefined || s.MozBoxShadow !== undefined;
}
The assumption is that the symbols will be defined only if the browser actually draws the shadow. This seems to be about right, the only exception I've found so far is the Webkit port to GTK (there's a bug report open).

Final point is Internet Explorer. As it turns out, there is a DropShadow filter. It's not terrible useful for this purpose, however. There are no soft edges, and it shadows the content rather than the containing box (it simply redraws the content with an offset in another color). So for my purpose I need to set a background color to ensure it's drawing a rectangle and not a text shadow. You could probably hack the lack of blurring with another filter, but in the end I went with a simple three-one-pixel-wide-lines approach that looks like my old hack but is much faster (updated, replaced the filter with a more appropriate one as suggested in the comments):
.shadowed {
background-color: #fff;
zoom: 1;
filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696', Direction=135, Strength=3);
}
This is served for IE only. The zoom: 1 is a hack to ensure that the element gets a layout (to work around the usual IE 6 bug).

So there you have it. Practical drop shadows. I will have to adjust the code a little bit as the other browsers get support, but I can live with that.

45 comments:

  1. Man, this is amazing!!! Realy amazing!!! This is the best solution and work´s fine!!!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. I like to use this in my website
      www.visitorbazaar.com
      May I use?

      Delete
  3. Good, but Opera 10.10 (current 21/01/2010) fails

    Only Opera 10.50 alpha wins

    thanks a lot

    ReplyDelete
  4. pixelzero: You still need another hack for old browsers. I didn't document that hack here, I only explained how to discover that you need it. :)

    I have one in action on YayArt.com, but it's a little bit complicated and has some caveats.

    ReplyDelete
  5. i have found the scripts for Opera from 9.5 (to the 10.50 version at this time) in your code (the common js).

    now i'm trying to apply to mupeditore.it

    thanks a lot

    ReplyDelete
  6. filter: progid:DXImageTransform.Microsoft.Shadow(color='#777777', Direction= 135, Strength=8);
    zoom: 1;

    Leaves a much better shadow, and its both easier to use, and looks a lot more like box-shadow :)

    ReplyDelete

  7. filter: progid:DXImageTransform.Microsoft.Shadow(color='#777777', Direction= 135, Strength=8);

    yes, cool, only one line make the same of eights

    ReplyDelete
  8. Yeah, switching

    filter:
    progid:DXImageTransform.Microsoft.DropShadow(color=#969696, offx=1, offy=1)
    progid:DXImageTransform.Microsoft.DropShadow(color=#C2C2C2, offx=1, offy=1)
    progid:DXImageTransform.Microsoft.DropShadow(color=#EFEFEF, offx=1, offy=1);

    out with

    filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696', Direction=135, Strength=3);

    I'll update the blog post. Thanks!

    ReplyDelete
  9. Hmmm, oddly enough your example doesn't work in IE 7 or IE 8 on my xp or vista installs. Just shows a grey box with no shadow.

    ReplyDelete
  10. works for me,
    XP sp3 ie8 and ie 7 & 6 with IETester

    ReplyDelete
  11. You could also do this to generate a rounded box-shadow ;)

    http://blog.citycrawler.com/?p=103

    - Daniel

    ReplyDelete
  12. Lovely trick indeed. Unfortunately does not work well with elements positioned absolutely that has :hover applied to it... Any thoughts to a fix guys?

    ReplyDelete
  13. to other not working try to put "!important" in css

    filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696', Direction=135, Strength=3) !important;

    ReplyDelete
  14. Hi,

    I'd recommend checking out http://www.modernizr.com/ . This is a great tool to determine not just the browser but specific browser functions like if it supports box-shadow. Than you have access to a class: .no-boxshadow to apply rules for browsers that don't support box-shadow.

    :Sam

    ReplyDelete
  15. works fine you make my day!

    ReplyDelete
  16. Thanks Ole!
    It doesn't work in ie8 compat mode - but better than nothing. Looks good in ie6 too... Yes some of my target audience may still be using this...

    ReplyDelete
  17. Awesome fix! Thx a lot!

    ReplyDelete
  18. WOW! It's realy best solution that i saw.
    Thx u!

    ReplyDelete
  19. Thanks.. working fine....

    ReplyDelete
  20. oh! just i was trying drop shadow to my input box, but i did not get solution for IE browser, my luckily i found solution in your website. Thanks for posting.
    Can i post same article to my blog. see this my blog: http://www.addcolours.com/blog

    ReplyDelete
  21. This solution is not working on IE 8

    ReplyDelete
  22. IE 8: it seems to work for me, when I visit YayArt with my IE 8 on Windows XP, I definitely get shadows.

    As one of the above comments mention, it may not work in IE 8 compatibility mode, I think this may be fixable, but really, you should get out of that mode as soon as possible because it means you're stuck with the old non-standard compliant renderer.

    ReplyDelete
  23. I still can't get this to work in IE9, I will try creating a sector just for IE.

    ReplyDelete
  24. Don't use the IE hack for IE9, it has native support for box-shadow: http://msdn.microsoft.com/en-us/library/cc351024(v=vs.85).aspx

    ReplyDelete
  25. Check out css3pie.com. It uses methods similar to this for many css3 styles in IE, and works really well, all things considered.

    ReplyDelete
    Replies
    1. css3pie is not work correct find curvecorner script and put ur site.and should must -moz-border-radius:10px;

      Delete
  26. You should still put the standard box shadow call below the -moz & -webkit so that when a browser fully adds the box shadow capability you are overriding the workaround (-moz and -webkit)

    ReplyDelete
  27. Had to switch it off on the shadowed content as the contained link hover states became unresponsive:

    .shadowed * {filter:none}

    ReplyDelete
  28. hre provide all ie solution.like box shadow,corner,text shadow.

    ReplyDelete
  29. and here also provide jquery script for box shadow,text shadow because it solution is not work in IE. so plz provide.

    ReplyDelete
  30. no shadow or round corner in ie9..... but css3 worked good at mozila, chrome, safari, opera, firefox.....

    fuck ie9.

    ReplyDelete
  31. Thank for share this great trick

    ReplyDelete
  32. IE9 supports box-shadow so you can stop moaning about that.

    ReplyDelete
  33. For IE6,IE7,IE8
    filter: progid:DXImageTransform.Microsoft.Shadow(color='#777777', Direction= 135, Strength=8);
    zoom: 1;

    But there is a problem cursor in area input box to apply with css filter.
    The cursor will display wrong position in input box when you key press them.
    Anybody know how to fixed ? Thanks....

    ReplyDelete
  34. Handbags are designed to complete any outfit that a woman might wear. This aspect of women’s apparel has been in the fashion world of the women for as long as anyone can remember. Women have found convenience in a Louis Vuitton replica handbags whenever they go out, as this is where they can keep safe their small belongings that they must have on them when they leave the house.Ever since modern bags initially appeared in France, designs have been in variation, and the indispensability of this item to women’s apparel has never been in question. The demand of this product has never declined since, generally, women desire to own a collection of handbags. And it doesn’t matter if they already have a closet full of them.Women prefer handbags according to many parameters. They may consider such factors as their age, personality, income, occasion, etc. But then the brand has always been the most important issue. Designer Louis Vuitton replica, no matter how remarkably-priced, are regarded as the ultimate addition to any collection of woman’s apparel. It is glorious to own such a remarkable possession. However, it also has some drawbacks. While an original replica handbags would make many women happy, it can definitely burn a hole in her pocket. There aren't too many women who could easily afford one. In fact, for some it may take an eternity to accumulate the kind of money that designer handbags normally cost.Fortunately for many, brand copiers entered the scene and filled this gap. Although it has been said that imitation is a form of flattery, this occurrence in the trendy fashion world has not been so particularly pleasing to replica Louis Vuitton handbags designers or brand owners. But for many women, this is an immediate alternative with numerous advantages. Replica handbags are widespread, available in almost all markets worldwide. If there is a proliferation of designer handbags in the world’s fashion market, replica handbags have more than doubled this number.Although, the quality of an original designer handbag can never be matched exactly by a replicated one, most women can easily afford a knock-off brand. And, after all, the difference between the two is not that significant. Basically, the features are the same except for the quality of material used. However, replica handbags cost about half as much as original-labeled designer handbags. So why spend double if you can get the same features?Finding replica handbags has never been easier.

    ReplyDelete