Flexible Drop Shadows #

While working on yet another pet project, I decided to add an alpha-blended shadow around a draggable container. Although I have done such things before (for the magnifier), up until now I have only needed this effect for fixed-sized objects. In this case, the container could have any dimensions (within reasonable bounds). After some experimentation, I came up with a method that used two sliding door style <div>s with a background image (I'm not a big fan of the cutesy names that the designer community chooses for CSS techniques, but such is life). The net result is visibible here.

Each image is wrapped in a shadow <div> that also has four inner ones for each corner of the image. These corner <div>s are absolutely positioned within the container. Two of them are rather small, and only have the non-repeated parts of the of the upper-right and lower-left corners as their background images. The other two corners also have background images, except they are much larger (1000 x 1000 pixels, though even larger sizes should be feasible since they compress very well). However, we only want to display part of these images, making them big enough to contain the inner <div>. We accomplish this by giving them heights and widths of 100%. We then use negative position offsets to move these four <div>s outward so that they do not overlap.

One issue encountered is that MSIE does not directly support PNG transparency. The usual workaround is to use the filter CSS attribute. However, it does not seem to support the relative pinning that regular CSS background images can have. Due to the lack of a workaround, the best I could come up with was to disable this effect for this browser. It can be done in JavaScript, but I chose to rely on MSIE's lack of support for the direct descendant CSS selector. As a result, all drop-shadow related rules are prefixed by html>body so that MSIE does not see them.

As a bonus, I also threw in an image loader that can load any URL and determine the image's dimensions with JavaScript. Since some browsers do not immediately populate the width and height properties of the JavaScript object, the solution was to use a timeout (via window.setTimeout), checking for these properties until they were non-zero (actually, until they were greater than 24, since MSIE seems to default to the placeholder's image dimensions until the real one is loaded).

Having done all this, I discovered that nearly the same technique has already been covered on A List Apart. I suppose I can take some pride in having come up with it independently, and also in the fact that my shadows go all the way around the image (though they are nearly imperceptible on the upper and left-hand sides), allowing for the possibility of fancier borders.

As a side note, it's interesting to see how my JavaScript coding style has improved since my earlier experiments. Now I use closures and other fun things. It's always good to know that your skills have room to improve.

Post a Comment