CSS tricks
February 6, 2006 7:27 PM   Subscribe

CSS tricks - cross-browser drop-shadow applied around a wrapper div without using transparent pngs?

CSS tricks - I'm trying to create a cross-browser, fixed-width css layout that includes a drop-shadow on the left, bottom, and right sides of the outer div and accommodates a patterned background image.

Example: sucidegirls.com viewed with firefox 1.5.
Note: the above design utilizes the transparent png approach, and does not work in IE 6. I'm trying for a cross-browser solution.

Important: as in the above example, the bottom of the page will have a margin such that the vertically-reapeating background image also shows at the bottom of the page. Thus, the drop shadow will extend from the body content to the page background.

Is there a cross-browser solution eluding my googling skills?
posted by masymas to Computers & Internet (17 answers total)
 
the above design utilizes the transparent png approach, and does not work in IE 6. I'm trying for a cross-browser solution.

If you're ditching transparent pngs, you're going to have to dive into the realm of custom IE effects. And if you're going to do that, you may as well just fix the png backgrounds using said custom IE effects.
posted by weston at 7:29 PM on February 6, 2006


this one will use the gifs for IE, while using the superior transparent pngs for browsers that support it.
posted by kooop at 8:47 PM on February 6, 2006


Ugh. I've struggled with the drop-shadow controversy many-a-time. The argument for is that it just looks so darned nice. The argument against is that it's such a royal pain in the ass to do "elegently."

There are way more ways to do this than you think. Just off the top of my head:
  1. With a table. I know, it's u-g-l-y code, but if it looks fine on the client's side, who's to know? And done right, it can be CSS-compliant. How nice.
  2. Relative or absolute-positioned elements with negative top and lefts. Works great until you need something not relative or absolute. Your CSS will start looking very ugly.
  3. Solid-color margins. Yeah, not nearly as pretty, but if you don't mind the fact that the top-right and bottom-left (on a standard drop-right shadow) edge will look like shit. Alternates to this include the infamous "sliding doors" method, substituting really, really big background images for shadows. CSS will require tweaking cross-browser.
  4. The browser-specific method: Use IE's built-in directx filter (boo) and for firefox use Mozilla-specific compounded border properties (-moz-border: #x #y ... #z; and -moz-border-radius: #px;. Drawbacks: are you fucking kidding me?
  5. Plus other options that are categorized under "eggregious use of the CSS properties."
  6. My advice is, just use tables and be done with it. And remember: if you even TOUCH a .PNG file, you're going to be in cross-browser-trouble thanks to IE's non-standard implementation. You can get around it by traversing the DOM of your page onload() and replacing any instances of IMG where (SRC.indexOf('.png') != -1) to include the directx filter. Though, that's ugly-ville if you ask me.

posted by Civil_Disobedient at 9:35 PM on February 6, 2006


Dang, look at me all "CSS-this" and "DOM-that" and I forget to close my damned list tag.
posted by Civil_Disobedient at 9:36 PM on February 6, 2006


Ok. Let me get this straight. You want an opaque, complex background. Over that you want an opaque css-controlled div for primary content, however you want its margins to contain a drop-shadow effect on all four borders relative to the background.

And you want it to have full cross-browser support.

Damn, that's a doozie to pull off. But with a bit of crunching shouldn't be impossible.

I hate to say this, but in this case I would recommend a series of wrapped divs with alpha-channel controls.

<div class="drop" style="width: 720px;">
<div class="drop" style="width: 719px;">
<div class="drop" style="width: 718px;">
...
<div class="content" style="width: 700px;">
...
</div>
...
</div>
</div>
</div>

The sucky thing is that you have to do this for about 20 layers before you start content in order to get enough pixels around all four edges. The good thing is that the css for your class tags is relatively straightforward.

.drop {
padding-bottom: 1px;
padding-top: 1px;
padding-left: 1px;
padding-right: 1px;
background-color: #000000;
opacity: .05;
filter: alpha(opacity=05);
-moz-opacity: .05;
}
.content {
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
padding-right: 10px;
background-color: #FFFFFF;
}

Notice how each div has a set width? IE requires this in order to properly use transparencies. Yes, there's a lot of repetition, but it gets the job done. Each one has a width 1 px different from its neighbors, with the final content div being the true desired width. The existance of all three alpha controls - in that order - is what's gonna make this float. Write those three down and keep them handy whenever you do cross-browser transparency.

You'll have to test exact values for padding and coloration for various effects. Remember that one browser responds to pads by adding more to the outside width but making the addition unusable in text flow while the other just moves in the limits of the text flow without adjusting actual div width. Fiddle with some of the numbers until it looks right.
posted by mystyk at 11:43 PM on February 6, 2006


I haven't tested it, but I bookmarked this a few days ago - seems to work fine in IE. Sample.
posted by blag at 5:30 AM on February 7, 2006


Um, that's some fine hackery, but I can see a couple of problems.
  1. That's not really getting around the "lightweight" issue at all. I mean, I could write a JS function that combed through the DOM and searched for any arbitrary object and apply a style to it, but that's a lot of JavaScript. I mean, it's nice that you can hide most of the hackery behind the scenes like that, but it's not elegant in the grand scheme of things.
  2. Not transparent. Change the background image to a solid color and you have to redo all the GIF's to match. Easy enough, just replace it with PNG's, right? Not so fast! The way this system works, you'll have one shadow (the corner image) hovering over another shadow (the background shadow). So the corners will look like shit.
There's really no getting around using tables. But here, if you want some bad-ass JavaScript hackery that will actually render the shadow properly, I'll cook you up something that works real nice.

With any luck, it'll even make the PNG's work automatically in IE without any extra code (that you can see, anyway). Watch this spot (if anyone's still reading).
posted by Civil_Disobedient at 4:46 PM on February 7, 2006


I'm still reading
posted by blag at 5:08 PM on February 7, 2006


Cool. I'm doing a little write-up and example. If anyone actually likes it, I'll do a more formal writeup and submit it to ALA. Some people are still apparently looking for the Holy Grail of this kind of stuff. Personally? Just use borders more creatively and ditch the whole "making the computer look like real life" thing.
posted by Civil_Disobedient at 5:25 PM on February 7, 2006


OK, I've got the shell of it working. The big problem I found was that most methods don't bother trying to make PNG's work with the shadows. That's fine if you know the background will work with your GIF's beforehand (and your background is a solid color). The other problem is that nearly all those methods (including blag's, which is pretty neat otherwise) is that they break horribly when you need to apply any real block-level styling to them. Centered DIV's screw it up. Float's will probably do the same. So that means you have to design an entire page around a cheap gimmick.

Anyway, later tonight I'll have hashed out the new and improved JavaScript routines. This shadow will support PNG transparency's across all (modern) browsers, support scaling of the shadow size, and support scaling to the container size.

And I also promise loads of JavaScript hackery.
posted by Civil_Disobedient at 5:05 AM on February 8, 2006


Oh, and needless to say, it'll be easy as heck to define. Something like:
<img src="whatever.jpg" width="500" height="500" class="shadow" />
...or...
<div class="shadow">Block-level element, text element, whatever-element goes here.</div>
posted by Civil_Disobedient at 5:08 AM on February 8, 2006


Splendid stuf, C_D. Look forward to seeing it
posted by blag at 7:20 AM on February 8, 2006


OK, it's still under development, but so far so good. Check it out here. I'll create a MeFi project for updates. Here you go.

Ah. Looks like you can't post comments to Projects. Oh well. Keep checking the main link for progress. I hope to have this working on all DOM block elements (text, images, whatever), it will (hopefully) support multiple-class objects (for example, applying a drop-shadow to a box with a border around it), the transparencies will work seamlessly in IE, and it will still be able to handle :floats and the like without any problems.
posted by Civil_Disobedient at 9:48 PM on February 8, 2006


Since Matt keeps these AskMe threads open for quite a while, and I link to this thread in the Projects post, I'll post any updates here.

There are still some kinks to work out, but it appears to be reasonably functional. And looks way better than the ALA version. :)
posted by Civil_Disobedient at 4:56 AM on February 9, 2006


Good stuff - will have a play with it and give you some feedback.
posted by blag at 5:36 AM on February 9, 2006


Update:

Updated the test page with the new routines I've been working on. You can see them for yourselves, and read my comments in the JS file if you're interested in how any of this stuff works. Doesn't like objects with margins or padding yet, otherwise works perfectly.

The container can now also be set to automatically compensate for the shadow width (useful for centered blocks).
posted by Civil_Disobedient at 9:13 AM on February 10, 2006


Interesting. I'm trying to remember exactly how Google did it, because IIRC, the drop shadows that they used in Google maps are transparent PNGs that were very carefully set up so that they would work in IE anyway. Might want to look into that.
posted by sporkmonger at 11:43 AM on February 24, 2006


« Older When you quit drinking, how long to look better in...   |   How does a first edition book compare to later... Newer »
This thread is closed to new comments.