Corners and shadows
iaian7 » code » webcode John Einselen, 18.02.08 (updated 17.02.09)While there are plenty of solutions for adding CSS based drop shadows to elements, few of them work with transparency, and even fewer of them can add a shadow to all sides of an object.
Apple.com (circa early 2008) has perhaps the nicest shadows I’ve found online, with subtle shading on all sides of their pop-up image viewer. However, upon inspection, it’s just a simple PNG image, and they’ve set their image overlay to a fixed size. Simple and effective, but hardly useful in situations where sizes can be fluid and content may change.
After trying to work with other methods I found online, I gave up and decided to develop my own technique. It’s not going to be a great solution in all situations (say, thumbnails in a large gallery), but for limited use (info boxes, page elements, etc.) it seems to be very effective.
Completely dynamic
Content can be of any size, and will even fluidly resize in the page. Because the corners and background are contained in one file, load times are also quite fast (a 1280×1280 PNG file with rounded corners and large drop shadow is less than 15kb), with all sides appearing simultaneously (no partially loaded shadows).
All sides
This technique allows for full styling on all sides of the element. Shadows can extend in any or all directions, as can corners, edges, etc.
Full transparency
Most rounded corner or shadow solutions rely on a flat background color and opaque images to work. Newer design standards, however, commonly make use of overlays or floating elements, and since the advent of IE7, all mainstream browsers support PNG files with full 8bit transparency. This technique leverages this, and allows for you to style not only the surrounding area (shadows), corners (rounded, or otherwise), and borders, but the entire content area as well. A single image can control the entire element’s appearance.
Completely cross platform
I’m really not sure how I lucked out, but the DOM and CSS setup has worked in every single browser I’ve tested in (except for the obvious, IE6, which never works with anything).
OS X – Safari 3, Firefox 2, Opera 9, Camino 1.5
Vista – Internet Explorer 7, Firefox 2
Valid XHTML
Again, not sure how I managed this, but it checks out fine!
Limitations
Because of the rather stringent nature of positional CSS, the containing DIV must be set to absolute or fixed position. If you want to position the elements inline with other content, you’ll have to wrap it with yet another DIV set to relative positioning. Even then, it’s difficult to get the space set up correctly; the technique is really quite a bit better for floating content.
Thanks to Ben Wolken for his help, and especially for figuring out that last nagging rounding error.
Example
HTML
Keep in mind that yet another DIV is needed if this content is to be displayed inline. I know, this isn’t exactly a small number of DIVs, which is why the technique isn’t a one-for-all solution. It’ll be great in some situations, not so fun in others.
If you don’t use photoshop yourself, download the image used in the demo above and upload it to your server.
<div class="boxwrap">
<div class="box">
<div class="boxtop"></div><div class="boxright"></div><div class="boxbottom"></div><div class="boxleft"></div><div class="boxcontent"></div>
</div>
</div>
CSS
The margin and padding settings determine the amount of shadow overhang that shows beyond the edges of the content. Because I’m using an image to define my content background as well, this wouldn’t change for me.
However, if you’re using this setup just for shadows (and setting the content background separately), you would be able to change the margin and padding settings to adjust how the shadow expands or contracts beneath the content.
#boxwrap, .boxwrap { position: relative; }
#box, .box { margin: 0px; position: absolute; left: 0px; top: 0px; }
#boxtop, #boxright, #boxbottom, #boxleft, .boxtop, .boxright, .boxbottom, .boxleft { position: absolute; width: 50%; height: 50%; background: url(http://iaian7.com/images/clouds/shadow.png) no-repeat left top; background-repeat: no-repeat; }
#boxtop, .boxtop { top: 0px; left: 0px; padding: 50px 0px 0px 50px; margin: -50px 0px 0px -50px; background-position: left top; }
#boxright, .boxright { top: 0px; left: 50%; padding: 50px 0px 0px 50px; margin: -50px -50px 0px 0px; background-position: right top; }
#boxbottom, .boxbottom { top: 50%; left: 50%; padding: 0px 50px 50px 0px; margin: 0px -50px -50px 0px; background-position: right bottom; }
#boxleft, .boxleft { top: 50%; left: 0px; padding: 0px 0px 50px 50px; margin: 0px 0px -50px -50px; background-position: left bottom; }
#boxcontent, .boxcontent { position: relative; color: #ffffff; }
Known Issues
This does not work in IE6, and after hacking at it for hours, I don’t care anymore. I’m sorry, but it’s just not worth the grief.
I’m having a problem with the background shadows. I’ve got it working on my site, but for some reason any buttons underneath the div boxes no longer work. It’s my buttons that use div background images that no longer work.
Thanks for any suggestions.
in ie6 it doesn’t work