PNGs are pretty, PNGs are nice. They can do cool alpha channel transparency... Um, except on the browser that almost everyone in the world uses/is forced to use. This has spurred many people with too much time on their hands to hack around the problems, usually so that they can make their weblogs prettier (it distracts people from the lack of content :)

The problem with many workarounds, however is that they tend to require silly amounts of text for each image, and implementation would mean hours of plodding through page after page replacing image tags with some gobbledygook. Well, here's a nice solution that means you don't have to do that sort of stuff...

The nicer Internet Explorer PNG Alpha workaround!

This basically works on the same principle as the above hack, but makes it automatic, meaning you just do the normal IMG tag and it takes care of itself...

First we make a file called pngbehaviour.htc filled with bizarre Microsoft-type extensions, which can change the behaviour of IMG tags to run some script. This script checks that the image is a png, and sets up the workaround if it is...

The file should contain the following gubbins:

<public:component>
<public:attach event="onpropertychange" onevent="propertyChanged()" />
<script>

var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
var realSrc;
var blankSrc = "blank.gif";

if (supported) fixImage();

function propertyChanged() {
   if (!supported) return;
   
   var pName = event.propertyName;
   if (pName != "src") return;
   // if not set to blank
   if ( ! new RegExp(blankSrc).test(src))
      fixImage();
};

function fixImage() {
   // get src
   var src = element.src;

   // check for real change
   if (src == realSrc) {
      element.src = blankSrc;
      return;
   }

   if ( ! new RegExp(blankSrc).test(src)) {
      // backup old src
      realSrc = src;
   }
   
   // test for png
   if ( /\.png$/.test( realSrc.toLowerCase() ) ) {
      // set blank image
      element.src = blankSrc;
      // set filter
      element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
                                     src + "',sizingMethod='scale')";
   }
   else {
      // remove filter
      element.runtimeStyle.filter = "";
   }
}

</script>
</public:component>

Done that? Good. Now all we have to do, is associate this with the IMG tag using some evil microsoft trickery. Add this to the CSS for the page:

img {
   behavior: url("pngbehavior.htc");
}

That's it! No silly stuff in image tags or hours pouring through old pages... any page that uses that CSS will now have fully transparent PNGs in IE!