Drop Shadow Technique (English)

Diesen Artikel gibt’s auch auf deutsch

Drop Shadows

Nearly all drop shadow techniques don’t suit my needs because the either rely upon IE filters (that the shadow is also visible in IE) or upon additional markup. Others have the problem that the corners are not smoothly rounded - and that doesn’t look very nice. The best thing: My method is not based on any additional markup and works completely without CSS hacks. First I want to show you the final result (you can see the effect only in modern browsers - the Internet Explorer is no modern browser).

The Idea

I don’t talk here about simple drop shadows but about an enhancement of already existing techniques. There are some people out there who already dealt with the problem drop shadows. Here is a (of course not complete) list:

But all these solutions have the problem that the corners don’t look very nice. The shadow ceases abruptly and does not phase out gently. But it works also in the Internet Explorer.

For every one who uses a CSS 2 capable browser (for example Mozilla, Opera or Safari) supporting the CSS pseudo elements :before and :after , there is a very simple solution of this problem - without using additional markup. This was the most important thing for me. No additonal markup like div-containers should be used as they would destroy the semantic of the whole web page.

My technique is also displayed in IE but you can just see the shadow without the smooth edges in Version 5 and up - that’s all. (like in Step 1)

The implementation

The markup

<div class="image">
    <img src="images/testbild1.jpg" />
</div>

The markup is actually very simple and consists only of the most important tags. A container for the picture and the picture itself. Even width and height specification is with my method (in contrast to for example the BefTer drop shadows) not necessary because the shadow adapts automatically to the image.

Step 1

.image {
    background:url(images/dropshadow.png) no-repeat bottom right;
    float:left;
}

.image img {
    display: block;
    margin: 0px 9px 9px 0px;
}

First of all the drop shadow image is defined and aligned at the right bottom corner. The float:left is required for the adaption of the container to the picture, else width and height specification would be necessary. But this is undesired as we would have to adapt the CSS for every picture. Of course you can replace the left also width right if you need it.

display:block for the picture itself is necessary, otherwise Safari would not render the shadow correctly. Subsequently we add a margin to the right and the bottom so that the shadow from the container appears. By the way, the lower picture is a semitransparent GIF-Image (this will be important later for demonstrational purposes).

Step 2

.image:after {
    background:#000000;
    display:block;
    width:18px;
    height:9px;
    content:"";
    margin:-9px 0px 0px 0px;
}

The pseudo element :after, which exists since CSS 2.0, adds a container after the element. That it appears at all, you have to set content:""; at first, even if it has no content. The second important definition is display:block;, after all we need a block for the lower left corner. The specification of the background color as black is only here that you can see the box better in the example. The background will be replaced by the drop shadow image later and will be like this: background:url(images/dropshadow.png) left bottom no-repeat;

After that we pull up the corner with a negative margin by 9 pixels (the height of the shadow), so that it is on the same level as the background image of the container. The width of 18 pixels is incidentially necessary with my picture as the transition is a bit longer than 9 pixels, but that isn’t wicked so far.

Step 3

.image:before {
    background:#FF0000;
    display:block;
    height:18px;
    content:"";
}

This step cost most of my time although it’s not visible in the resulting CSS. At first I always specified the width (mostly 9 pixels) and dragged the container with margin-left:100% to the mostright. But this resulted in different representation in Mozilla and Opera, what is, of course, not acceptable. Using a browser switch or even a hack is not an alternative - and this kept me experimenting.

As a matter of principle :before is constructed equally to :after, indeed there are some minor but very important changes: As described above the width is not specified - the container extends like a normal div as wide as possible. And this is exactly right above the right shadow. The height is - like the width in the :after-Element - specified with 18 pixels, so that the shadow transition can be shown completely.

Step 4

Finally there is the problem that the :before-Container is not shown above the picture but simply below. But the container has to overlap the background shadow next to the picture - and not above it.

margin:bottom:-18px; in the :before-Container answers this problem by “pulling” up the picture by 189 pixels. Now replace the two background colors in the :before and after :after containers with the right picture and the drop shadow is complete

Compatibility

I tested this technique with all browsers at my disposal and the drop shadow is shown correct in these browsers:

  • Mozilla Firefox 0.9.3/Windows XP (and probably also in all Mozilla derivates)
  • Opera 7.53/Windows XP (possibly also in older version, but I have installed none of them)
  • Safari 1.2/Mac OS X 10.3

In these browsers the shadow displays without smoothed corners:

  • Internet Explorer 5.0, 5.5 und 6.0/Windows XP

Further compatibility reports or incompatibility reports and suggestions for improvement are of course appreciated.

Comments

1
A fan on December 5, 2005

Many thanks for this very nice drop shadow effect, a really good job !

2
Rich on February 9, 2007

Thanks for the great post and for all the effort that went into researching this solution. Would it be possible for you to share the image png/gifs for the drop shadows too?

Rich

3
Bubbila on March 24, 2008

Sweet tutorial, just what I have been looking for. I have added you to Stumbleupon.

4
ritchie on October 28, 2008

Thanks, great tutorial - unfortunately I found it too late, after having decided to live with the ugly corners. I’ll definitely use this technique for my next template though.

5
Mark on November 11, 2008

This looks awesome - I’ll give this a go as it appears to be just what I was looking for.

I’m surprised I’ve not come across more people making use of :before and :after