With the expanding support for PNG, it has become more and more frustrating to be prevented by IE's lack of support to fully use PNGs. We will try to find a way to bypass IE's limitations (until the next vesion comes out and hopefully solves the problem) by showing it what it can display, and by giving PNGs to more modern browsers.

Quick definitions

PNG

Portable Network Graphics. This format was designed as a means to replace GIF, originally because of a royalty question. But it expands GIF's transparency capacity by managing full 256-level alpha-transparency. See the W3C's recommendation.

GIF

Graphics Interchange Format

This format is not royalty-free, and has limitations. Yet it has been a de facto standard for transparent images on the web since the 89a implementation.

CSS

Cascading Stylesheets. But you knew that, didn't you?

For a more detailed description of the technical aspects of both, please refer to To PNG or not to PNG.

The situation at hand

So, Internet Explorer does not manage PNGs but you would very much like to have a nifty semi-transparent background to blend it better with your background. So far the solutions for IE have mainly involved Javascript, as a simple javascript alpha transformation method (see the example below), or more subtly, as a behavior method after the example of WebFX.

A 'simple' javascript alpha transformation method: too many drawbacks!

This is what I found, with the help of the Pompeurs mailing-list: Internet Explorer can replace a background by another, and in the process get the exact alpha transparency for each pixel of the new background image. Then it applies a filter and gives the expected result: alpha-transparency!

// this function finds the 'logo' element in my HTML and replaces its background

function init() {

// is the browser competent with the DOM?

if(document.getElementById) {

// is the browser capable of managing runtimeStyle?

// (this would mean, basically, "hey, I'm IE")

if(document.getElementById('logo').runtimeStyle) {

// delete current background

document.getElementById('logo').style.backgroundImage = 'none';

// apply PNG background with alpha transparency filtering

document.getElementById('logo').style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='logo.png',sizingMethod='scale')";

}

}

}

window.onload=init;

But there are serious drawbacks with this method, which I have learnt the hard way:

Hacks are to be avoided, yet they're sometimes unavoidable

I fully endorse Peter-Paul Koch's statement: Keep CSS Simple! For those of us who have been in the web trenches for a few years, hacking around one browser's limitations reminds us of countless nights writing proprietary javascript, proprietary tags, multiple versions of a given page, and whatnot. Yet like with many things in life, simple hacks are sometimes unavoidable; but in this case they should be as limited as possible: extensive hacking means sleepless nights, trust us.

There are simple and not-so-simple ways to hide some CSS to some browsers, mainly based on their flawed implementation of constantly-improving CSS standards. There are even pretty complete lists of more or less ugly hacks based on commenting and commenting-into-comments, backslashing, etc. See Centricle's CSS filters chart for a pretty thorough example.

What? Did I say "ugly" a second ago? Sorry to sound pejorative. I meant it is going quite difficult to maintain and re-read your CSS in a few months' time when you write this: /*/*//*/property:value;/* */ or that: /*/*/property:value;/* */. You have to write extensive documentation and keep it at hand, right?

OK, hacks are ugly, but here is a simple one I found while dealing with the issue: IE (like all the old browsers) does not understand child selectors (the > character). So let's give IE what it wants: a GIF background. More modern browsers will display the PNG, because one expects them to both understand the child selector and be able to display PNGs properly.

What about this piece of CSS code:

/* this line give you a nice, if less sexy, GIF background */

div.bg_hack { background:url('ceci_est_un_gif.gif') no-repeat top left transparent; }

/* PNG power! */

body > * div.bg_hack { background:url('ceci_est_un_png.png') no-repeat top left transparent; }

Here is the GIF/PNG background hack in action.

Side note

Since I came up with this idea, an article about CSS drop shadows was published on A List Apart that uses IE's inability to understand the !important CSS statement. Fair enough, it's yet another way to do the same thing. But for the sake of readability I prefer to stick to the child-selector for the time being.

Conclusion

Of course this is a hack, so it can generate problems on its own. Non-flat-colored backgrounds can show the rugged edges of the GIF in Internet Explorer (this is what I show in my example, see the funky part of the page. And either because of petitions, or because people at Microsoft are clever and will modify subsequent versions of IE, or just because history will force them to do so (and this is not the place to discuss this), one day or another we may end up finding this hack unnecessary.

Until then, this will do the trick, in my book.

Afterword

Please feel free to report any weird behavior. So far I have tested it with Opera, Mozilla, IE5.5/Win and it behaves like it should. I have no access to Safari, for example, but I hear its CSS support is excellent.