The Best Damn Drop Shadow Ever Tutorial
Here are the images
shadow.png
leftcorner.png
rightcorner.png
This tutorial is pretty much obsolete. Now use CSS3 box-shadow instead.
This one took me a while. I was looking for the best and most flexible drop shadow technique that there was. If you've looked, you know that there are quite a lot of different ways to achieve a drop shadow. However, which ever method I chose to use had to have a couple things in common. First and foremost, my drop shadow had to look good! It also had to be a transparent .png, it had to give me the flexibility to use an <img> tag or a background image, and give me the flexibility to apply the drop shadow to any element that I wanted, be it a div, img, p, h1, you name it! Oh ya... and it had to have the ability to automaticaly adjust in size to any size element I applied it to. As you've probably guessed, this narrowed my choices down considerably. After a week or two of looking and trying different techniques, I finally found what I was looking for at Big John's site Position is Everything! For a very detailed explanation of this technique read his tutorial on drop shadows.
If you know me, you know I like clean, minimal, and easy to understand code. So I took Big John's Method and simplified it, cleaned it up a little, recoded it so there is less CSS/HTML to deal with, and wrote it up in a way even my grandma can follow. Oh ya... and coded up so you can get it working in IE6 as well. While I was working with this I coded it three different ways, they each perform the same - so take your pic! This first method was the code that I chose to use on my site because of it's minimal amount of html - so it's the one I'll focus on in this tut. The two other coding techniques will follow down below. Note: I included the same image in the html as an <img> and as a background image in the CSS so that you can see that it works the same either way, and also so you can see where to put a backgound image in the CSS if you so desire.
The CSS
.shadow { background: url(images/rightcorner.png) top right no-repeat; float: left; } .shadow div { background: url(images/leftcorner.png) bottom left no-repeat; padding: 8px 0 0 8px; } .shadow span { background: url(images/shadow.png) bottom right; display: block; } .shadow b { position: relative; left: -8px; top: -8px; height: 214px; width: 150px; display: block; background: url(images/family-photo.jpg) 0 0 no-repeat; } .shadow img { vertical-align: bottom; }
The html
<div class="shadow"><div><span><b> <img src="images/family-photo.jpg" alt=""> </b></span></div></div>
Pretty damn clean uh? Ya I'm proud of it! Just a couple things to note though. The div with the class of shadow needs to shrink wrap around the other block level elements. There are three ways to make it do that. By floating it either left or right, by positioning it absolutely, or by giving it a width plus the 8px of space it needs for the shadow. As you can see, I floated mine left in the example. The div with the class of shadow is also the one that interacts with things around it. So any positioning with margins or whatever needs to be applied to it and not the other block level elements that go into making the shadow.
Also, if you are not using any images in your html then you can safely do away with .shadow img {vertical-align: bottom;}. There are also a couple of different ways I found to achieve the same fix. Some work better than others in different situations, so I'll just list them all here directly below and let you be the judge. However, I found that vertical-align: bottom; works the best in the most possible situations with the least amount of side effects (actually, none that I found). display: block; works well but fubared my drop shadow in IE7 when a link was placed around an <img> tag. font-size: 0; works just as well as vertical-align: bottom; but makes your font-size equal zero, so you would then have to override it if you were using the drop on a div with some text in it. And overflow: hidden worked well but not in all browsers in all situations. So lets just stick with the one that I chose unless proven otherwise.
.shadow img { vertical-align: bottom; } .shadow img { display: block; } .shadow { font-size: 0; } .shadow { overflow: hidden; }
Now if it weren't for IE6 we'd be done - so simple, so sweet! But, at the time of writing this IE6 is still a factor. Of course you can always just hide your drop shadow from IE6, or override the rules, as Big John did and later talks about at the bottom of his article. But thats not me - I like the challange! After a lot of time looking for a png fix that works with this method I finally, and reluctantly gave up - it does not exsist. You see, this drop shadow is using backgound images that have been positioned. The fact that they're positioned removes any hope of finding a cure for our png in IE6. Trust me on this one, I looked for quite along time! If your placing your drop shadow on a solid color background then the easiest way is to just feed IE6 a gif instead. So if you know how (it's really easy), just go into Photoshop and give the png a solid color background and save it as a gif. Then just feed IE6 these rules directly below.
* html .shadow { background: url(images/rightcorner.gif) top right no-repeat; } * html .shadow div { background: url(images/leftcorner.gif) bottom left no-repeat; } * html .shadow span { background: url(images/shadow.gif) bottom right; }
However, if your not placing your drop shadow on a solid color background (a gradient or something) then of course a simple gif image will not be of any help to you. So while playing around with different things I came up with this - I'm sure some will find it useful. Aside from excluding the drop shadow altogether, it's a nice way for our drop shadow to degrade gracefully. If your situation matches what I've just expalined, and you're still bound and determined to give IE6 a drop shadow, then just feed IE6 these rules directly below. It uses the same png image so you can place it on any color background. It just gives it a less shadowy look and makes it more blocky looking. But it looks pretty good! Here, viewing in IE6, have a look for yourself! And after all that moving around, via negative margins and such, it puts it right back in it's orignal position so that it sits in the same exact place as all the other browsers. And there you have it - the best damn drop shadow ever - period!
* html .shadow { background: none; margin: -4px 0 0 -4px; } * html .shadow div { background: none; } * html .shadow span { margin: 0 -4px -4px 0; padding: 4px 0 0 4px; }
As promised, below are the other two ways to code this thing. The first is using plain old classes, but you may feel more comfortable, or semantically correct, coding it that way. The second method, is using child selectors. It is the cleanest code of the bunch, and the one that I would have chosen to use, but it leaves IE6 out in the cold because it does not understand them. So... there you go! That should keep you busy playing and testing for a while!
Coded With Classes
The CSS
.shadow1 { background: url(images/rightcorner.png) top right no-repeat; float: left; } .shadow2 { background: url(images/leftcorner.png) bottom left no-repeat; padding: 8px 0 0 8px; } .shadow3 { background: url(images/shadow.png) bottom right; } .shadow4 { position: relative; left: -8px; top: -8px; height: 214px; width: 150px; background: url(images/family-photo.jpg) 0 0 no-repeat; } .shadow1 img { vertical-align: bottom; }
The html
<div class="shadow1"><div class="shadow2"><div class="shadow3"><div class="shadow4"> <img src="images/family-photo.jpg" alt=""> </div></div></div></div>
Coded With Child Selectors
The CSS
.shadow { background: url(images/rightcorner.png) top right no-repeat; float: left; } .shadow>div { background: url(images/leftcorner.png) bottom left no-repeat; padding: 8px 0 0 8px; } .shadow>div>div { background: url(images/shadow.png) bottom right; } .shadow>div>div>div { position: relative; left: -8px; top: -8px; height: 214px; width: 150px; background: url(images/family-photo.jpg) 0 0 no-repeat; } .shadow img { vertical-align: bottom; }
The html
<div class="shadow"><div><div><div> <img src="images/family-photo.jpg" alt=""> </div></div></div></div>