More CSS Drop Shadows For All Browsers

Thanks to the unstoppable advancements of web standards aiding mankind to overcome the real burdens of the 21st century, adding drop shadows to boxes became much easier in recent years! No more PNG background images! Leaving the question aside whether drop shadows are really progressive and appropriate for a flat medium (anybody remember the fad of “3D” bulging buttons in the 1990ies?), I was confronted with the challenge of adding box shadows in Internet Explorer for a client project.

Pro tip: communicate to the client that shadows are a bonus feature. Your designers may disagree, but the site will not suffer considerably when special effects like box shadows, text shadows, or rounded corners are regarded as enhancements for decent browsers. However, your client’s budget will suffer when they are determined to provide the same visual effects on outdated browsers such as IE6. That said, here is the well-known method in CSS3:

  1. .wrapper {
  2. background-color: #fff;
  3. border: 1px solid #d30d01;
  4. box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2);
  5. float: left;
  6. height: 75px;
  7. margin: 15px;
  8. padding: 10px;
  9. width: 75px;
  10. -moz-box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2);
  11. -o-box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2);
  12. -webkit-box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2);
  13. }
  1. <div class="wrapper">
  2. <p>CSS box-shadow</p>
  3. </div>

At the same time when we rolled out the website, Robert Nyman came to the conclusion that the proprietary Microsoft filter for Shadow looks much prettier than DropShadow, so I forgot about blogging myself as his solution doesn’t rely on unsemantic markup and is more elegant:

  1. .wrapper {
  2. /* For IE 8 */
  3. -ms-filter: progid:DXImageTransform.Microsoft.Shadow( Strength=5, Direction=135, Color='#999999' );
  4. /* For IE 5.5 – 7 */
  5. filter: progid:DXImageTransform.Microsoft.Shadow( Strength=5, Direction=135, Color='#999999' );
  6. }

Note that you get slightly better effects when you choose a dark gray instead of black as shadow color. If you can live with the rendering of the third box below, don’t read any further. ;)

However, applying the filter had the side effect that text inside the box wasn’t anti-aliased in IE 6-8 anymore, and the shadow still didn’t look decent enough. So we added an extra span and applied the blur filter on it.

Screenshot comparing the solutions for CSS drop shadows side by side

That led to a more complex code as we needed an inner wrapper where the border and background is applied to, while the outer wrapper merely acted as a … wrapper, where the styles were reset to defaults. HTML first:

  1. <div class="wrapper ms-box-shadow">
  2. <div class="inner">
  3. <p>Internet Explorer with blur filter</p>
  4. </div>
  5. <span class="shadow"></span>
  6. </div>

And here’s the CSS that’s added with Conditional Comments for IE 6-8 only (as IE9 supports native CSS box-shadow, more or less). The shadow element is absolutely positioned, set behind the inner content and blown up to 100%. Not original, but it works:

  1. .wrapper, .inner {
  2. background-color: #fff;
  3. border: 1px solid #d30d01;
  4. height: 75px;
  5. padding: 10px;
  6. position: relative;
  7. width: 75px;
  8. }
  9. .wrapper {
  10. float: left;
  11. margin: 15px;
  12. }
  13. /* reset wrapper styles to defaults; work-around for screwed box-model */
  14. .ms-box-shadow {
  15. background-color: transparent;
  16. border: 0 none;
  17. height: 95px;
  18. padding: 0;
  19. width: 95px;
  20. }
  21. /* Move the inner wrapper to the foreground */
  22. .inner {
  23. z-index: 50;
  24. }
  25. /* The shadow element */
  26. .shadow {
  27. background-color: #000;
  28. display: block;
  29. filter: progid:DXImageTransform.Microsoft.Blur( makeShadow='true', pixelRadius=4, shadowOpacity=0.30 );
  30. height: 100%;
  31. left: 0;
  32. position: absolute;
  33. top: 0;
  34. width: 100%;
  35. z-index: 0;
  36. }

For some reason I got a more similar result with the shadowOpacity set to 30% instead of 20%.

Where’s the crux?

If we are willing to ignore lots of bloated CSS: IE6 only blows the shadow up to 100% when the wrapper has a fixed height. This sucks, but unless you want to add more bloated code in JavaScript I don’t know of any solution for this problem. Still IE 7-8 handle a value of 100% right, and there are many cases where the height is known. Take for example photos where you’d like to apply shadows, some buttons, or horizontal shades lying above images, like the shadow of the second level navigation on this site. Beautiful, isn’t it?

Comments are closed.