Display image PNG in Internet Explorer 6

The JS code can be seen if you do a “View Source” on the Solution page. There are two ways to use it - simple copy & paste or the JS include file method. Note that you must have height and width attributes specified for each image. Other attributes (class, alt, title & style) are optional so far as this routine is concerned, but are respected if specified.

There is also an imagemap version if you want to use imagemaps and/or form input images and a rollover version which enables the use of transparent PNGs in rollovers.

Method 1: Copy & Paste

For single page or occasional usage, copy the JS code in its entirety (from <!–[if lt IE 7]> to <![endif]–>) and paste it into your page somewhere in the the <head> section. That’s it.

Method 2: (recommended) JS Include File

If you wish to use the code on multiples of pages, you may prefer to use a JS include file. First, download the JS file here: pngfix.js. Place the file in your webpage directory, then add the following construct on each of your pages somewhere in the <head> section:

<!--[if lt IE 7.]>
<script defer type="text/javascript" src="pngfix.js"></script>
<![endif]-->

Note the use of the defer keyword. This trick causes the images to be replaced before they are rendered. Earlier versions of this script did not use this method, occasionally resulting in an unpleasant screen flicker as the PNGs were being filtered. The code in the include file is slightly different from the copy and paste code referred to above, so I recommend downloading my file rather than making your own.

Here is a demo page using the Include file method. This method is arguably better for use with multiples of pages, as it only requires three lines of code per page. The JS file is only 2KB in size and will be cached after the first download. It will therefore incur no further download overhead on subsequent pages. The download time should be around 0.3 seconds on an average 48kbps dial-up modem connection.

How It Works

I left the code uncommented for the sake of brevity, but the explanation below should suffice should you wish to hack it up or improve it.

If used inline, the code runs after any existing onLoad code has completed. If used as an include file, the DEFER keyword ensures it is run when the DOM has loaded, but before the images are rendered. It converts each PNG image into a span with the PNG’s width and height attributes. The IE 5.5+ AlphaImageLoader filter is then applied to fill each new span with the original image. It is this filter which allows PNG transparency to work correctly - see KB 294714 for more details. Alt attributes are converted to titles for mouse hover text. Any existing in-line CSS declarations plus title, ID & class attributes are transferred to the new spans.

Each new span has the declaration display:inline-block added - this enables the fix to work with “Standards mode” IE6 Doctypes. Finally, each replaced PNG is checked to see if it has the (deprecated) align=”left” or align=”right” attribute. If so, an appropriate CSS float declaration is added in-line in order to replicate the original alignment. Also, if the original image was used within an anchor as a link, then a hand cursor is applied to the new span in order to replicate the original link image cursor.

Variations

I was asked to amend the thing for pages with large numbers of images in order to reduce the initial flash of ugly border sometimes seen before the code does its job. I did not include these ideas in the original method as they break the “copy & paste” model somewhat, but they may nonetheless be of use:

(1) CSS Hide

Use a CSS class to hide your PNGs by setting visibility:hidden, then have the JS reveal them again after the transformation by adding visibility:visible straight after sizingMethod=’scale’); so that the whole line looks like:

strNewHTML += "(src=\'" + img.src + "\', sizingMethod='scale'); visibility:visible\"></span>"

Caveat: if the user has CSS enabled and JS disabled, then the images will remain invisible!

(2) JS code on individual PNGs

This method does no checking for deprecated img align=”left” or align=”right” attributes. It also breaks the non-invasive JS principal somewhat in that it is specifically called by selected PNG images on load in all JS-supporting browsers. However, while the function is called in all browsers, it only actually does something in IE 5.5 and 6.

var arVersion = navigator.appVersion.split("MSIE")
var version = parseFloat(arVersion[1])

function fixPNG(myImage)
{
    if ((version >= 5.5) && (version < 7) && (document.body.filters))
    {
       var imgID = (myImage.id) ? "id='" + myImage.id + "' " : ""
	   var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : ""
	   var imgTitle = (myImage.title) ?
		             "title='" + myImage.title  + "' " : "title='" + myImage.alt + "' "
	   var imgStyle = "display:inline-block;" + myImage.style.cssText
	   var strNewHTML = "<span " + imgID + imgClass + imgTitle
                  + " style=\"" + "width:" + myImage.width
                  + "px; height:" + myImage.height
                  + "px;" + imgStyle + ";"
                  + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
                  + "(src=\'" + myImage.src + "\', sizingMethod='scale');\"></span>"
	   myImage.outerHTML = strNewHTML
    }
}

To implement this only on specific PNGs, add the following to each PNG image you wish to transform:

<img src="xyz.png" alt="foo" width="10" height="20" onload="fixPNG(this)">

NB: You must have height and width attributes specified.

Rollovers

Mouseover tricks are usually used to swap images. The standard PNG fix function will break these, as it converts PNG images into spans. There is a way around this, depending on your requirements. If you need this functionality, check out the mouseover demo page.

Imagemaps & Input Images

Imagemaps and images used as form inputs do not work with the regular pngfix, but there is a special version you can use which requires an additional single pixel image in order to work. If you need this functionality, check out the imagemap & input images page.

Other Solutions

There are many other solutions to this problem - you may wish to check them out to see if they better fit your needs:

Fred Boyle emailed me with a Flash solution. He says you can “simply import the PNG into Flash and use the generated Flash movie using the WMODE parameter set to “transparent”. This works wonderfully!” . I am not a user of Flash so cannot comment on this approach but hopefully some may find it helpful.

http://homepage.ntlworld.com/bobosola/index.htm


You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

AddThis Social Bookmark Button

Leave a Reply

Spam protection by WP Captcha-Free