PNG Image Fix For IE

SUN, 18 NOV 2007

If you are a web designer, you know that PNG image rocks for its fine transparency support. But lacking of support on IE6 and below, probably has gotten into your nerve at some point of your life.

The journey for PNG image fix on IE has started long ago, and it all voices back to the use of AlphaImageLoader filter hack.

<div style="height:400; width:400; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png', sizingMethod='scale');"></div>

Some guys wrote Javascript codes to automatically reload PNG images found in image tags with AlphaImageLoader, an example would the pngfix.js by Bob Osola, the first you will find if you search for “PNG fix” on Google.

But the problems with Bob’s script, it fixes only the <img> tags, how about your <div> tags with PNG image background, and if you have small images, like an icon that I had with 12px height, the width and height will be distorted.

That will lead you to find a better solution to solve these two problems, and you may have bumped into TwinHelix IE PNG Fix or other similar solutions.

It fixes both <img> and <div> tags, and solve the width and height distortion through the use of blank.gif. On top of that, it uses a clever way of calling the javacript codes through CSS behavior attribute, supported only by IE, which gives you more choices on which element to fix.

img, div.img {
    behavior: url("pngfix.htc");
}

And human is definitely an amazing creature, whom can not be easily pleased. Two weeks ago, Rogie King from Komodo Media, published a clever way to PNG fix through CSS. Now you do not even need an external file, such as pngifx.js or pngfix.htc.

The concept is similar except it is neater and cleaner, and the javascript codes are compacted and called inline from behavior attribute. After all, PNG images are more of a styling issue, thus putting the fix under CSS seems to make more sense.

This is the best I’ve seen so far to solve my PNG image transparency issue, probaby yours too. Thank you Roque.

UPDATE:

Here are the quick step-by-step instructions, as requested by some:

  • Download pngfix.css, file created for your convenience.
  • Download blank.gif, a transparent 1×1 pixel image to help out with the fix, mouse right click and save it to /images folder.
  • If you store blank.gif in other folder other than /images, please edit pngfix.css to relect blank.gif location.
  • Copy the following code snippet and paste it in your HTML source codes, inside <head> tag, to load pngfix.css only for IE 6 and below; IE 7 doesn’t have PNG transparency issue.
    <!--[if lt IE 7]>
      <link href="/stylesheets/pngfix.css" media="screen" rel="stylesheet" type="text/css" />    
    <![endif]-->
    
  • That’s all, for all <img> tags with transparent PNG images will be automatically fixed, while for background images defined in stylesheet, you will need to add "png" class name to the respective elements, e.g. assuming that “flower_bg” defines a transparent PNG background
      <div class="flower_bg png">
         Hope you get a clear picture now.
      </div>
    

TIP:

On some cases if you have a lot of <img> tags with only a few of them are transparent images, you can choose to remove * html img selector for performance reason (remember to remove the comma as well). Without that, you would have to add "png” class name for <img> that needs the tranparency fix.

UPDATE 2:

Original script may cause redundant background ‘none’ call to the server, which may be shown as page not found or server error in the access log. I did some fixes which solve this issue, more about this issue can be found here. Here are the updated version, I’ve also updated pngfix.css, the downloadable version.

* html img,
* html .png {
  azimuth: expression(
    this.pngSet?
      this.pngSet=true : 
        (this.nodeName == "IMG" ? 
          (this.src.toLowerCase().indexOf('.png')>-1 ? 
            (this.runtimeStyle.backgroundImage = "none", this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')",
                this.src = "/images/blank.gif") :
            '') :          
          (this.currentStyle.backgroundImage.toLowerCase().indexOf('.png')>-1) ?
            (this.origBg = (this.origBg) ? 
              this.origBg :             
              this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
              this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "', sizingMethod='crop')",
              this.runtimeStyle.backgroundImage = "none") :
            ''
        ), this.pngSet=true
  );
}

NOTE:
Note that the disadvantage of using PNG Fix is when you are fixing a background image, your image position will be always set to top left (0, 0) and repeated or tiled background will not work. The workaround for the positioning issue is to create an image with the spaces required from top left, for tiled background, I guess there’s nothing much we can do about it other than to avoid the fix.

41 Comments . Comments Feed . Trackback URI
Thu, 6 Dec 07 12:06 pm . Eric wrote:

Great Find!
Will give it a try soon.

I find that the problem with the pngfix is the long loading time.
Can be quite a while for the png images to render before it load the whole page, and the png background on css, which I could not align the background png images to the right in the DIV.

Thu, 6 Dec 07 02:41 pm . Herryanto Siatono wrote:

Yeah I hate the slow loading time as well, sometimes I took out “* html img” filter, and just use “* html .png”, and just add the class=’png’ to relevant images that need the transparency fix.

Fri, 22 Feb 08 03:05 am . Andy wrote:

This doesn’t work for css backgrounds, does it?

Fri, 22 Feb 08 10:45 am . Herryanto Siatono wrote:

Andy, It does work with css background.

Tue, 11 Mar 08 01:49 am . Jay wrote:

This isn’t working for me…is that snippet of the css ending in “…” all of the necessary code?

Tue, 11 Mar 08 08:41 am . Herryanto Siatono wrote:

It’s not a complete code, you’ll have to click on the link to Komodo Media, but the site at the moment, probably try it again some other time.
http://komodomedia.com/blog/index.php/2007/11/05/css-png-image-fix-for-ie/

Sat, 15 Mar 08 10:46 pm . douglas wrote:

This is the best fix I’ve seen. The fact that your can tile a background png in ie 6 is HUGE. That makes a big difference in having to deal with this stupid ie browser for another year or so. This fix has allowed me to put a huge number of hacks away. Thanks!!!!!!!!

Thu, 3 Apr 08 03:49 am . Lemu wrote:

Some one tested it and have some sample to show what is necessary to do STEP BY STEP….. thank you

Tue, 8 Apr 08 03:20 pm . Nils Hendriks wrote:

Hi. Sorry, but I do not see the need for so much code and javascript at all. What’s wrong with placing the filter in a separate CSS file that is fed to IE through conditional comments? To me that seems to be the cleanest and leanest solution…

Tue, 8 Apr 08 09:38 pm . Herryanto Siatono wrote:

Nils, I guess it’s a matter of preference, for those with developer background, they may not like the lengthy declration of the filter in seperate CSS. For peole like them, including me, it’s a bliss to be able to just declare a class name and solve the problem. :)

Wed, 9 Apr 08 06:04 pm . Herryanto Siatono wrote:

@Lemu, please find the step-by-step instructions as requested.

Thu, 10 Apr 08 03:57 am . Adam wrote:

Great fix. I tried it and I am getting trasparency and images, but the image has a broken link behind it.

Thu, 10 Apr 08 03:18 pm . Herryanto Siatono wrote:

Forgot to mention that you’ll need to download blank.gif to /images folder, instructions updated.

Thu, 10 Apr 08 10:06 pm . Christine Walker wrote:

This is a great solution and so easy to implement. Thanks so much.

Fri, 11 Apr 08 12:55 am . CMN wrote:

There is a code difference between the version from “download link” vs the one presented on table above - “*html. img” is missing in the former. That makes the difference in

While, i have no luck in the Stylesheet image. Can i have more detailed explanation on how we put in ? Where do we include this ? All words “box png” in ?

Fri, 11 Apr 08 01:54 am . Herryanto Siatono wrote:

@CMN, Thanks for the note, I’ve updated the .css file to be in sync, the difference is with * html img, it iwill automatically pick up <img> tags and fix the png transparency issue.

On some cases if you have lots of img tags with only a few that requires transparency fix, you can choose to remove it, and you would have to add “png” class name for <img> that needs the tranparency fix, for performance reason.

<div class=”box png”>…</div> is just an example assuming that “box” contains background image defined in the css, I’ve changed it to “flower_bg” to avoid confusion.

Fri, 11 Apr 08 02:02 am . JK wrote:

Be aware that setting this.runtimeStyle.backgroundImage = “none” causes IE to call “none” from the server. If you have a lot of images, that is a lo of calls for a non-existing file. Check your fiddlers.

Fri, 11 Apr 08 12:39 pm . Herryanto Siatono wrote:

@JK, thanks for the note, noticed that as well, but was just too lazy to look at it previously, coz I knew how to avoid it.
Anyway, just fix it, more about it at:
http://www.pluitsolutions.com/2008/04/11/solving-css-png-fix-background-none-call/

Mon, 12 May 08 11:30 pm . _megankish__ wrote:

AWESOMENESS! This saved my life! I have used a couple other png fixes before, but that loading time was a real drag. It took me a couple of times to get this right with the location of my blank.gif but I got it working! I was also excited to see that it fixes the small image distortion. I had small images of folders on the homepage and they were slightly distorted and I couldn’t figure out why!

You have an awesome brain!

thanks!

Thu, 22 May 08 07:08 am . JT wrote:

Someone mentioned that you could tile a png but this didn’t work for me. Does this really work?
Thanks!

Sat, 24 May 08 11:47 am . Herryanto Siatono wrote:

Sorry JT, I don’t think it works with tile background.

Sun, 1 Jun 08 06:42 pm . Jeremy wrote:

This is a great solution. However, I have a problem on my website, I think this is because I’m using Google Maps API.
The page is very slow and it’s like there is always some code running. Also the map doesn’t appear at all.
Is there a way to exclude a div in a css selector ?

Mon, 2 Jun 08 02:10 am . Herryanto Siatono wrote:

div selector is not included in the default css fix,
* html img, * html .png. You may want to try remove “* html img” selector instead.

But on any img that needs the transparent fix, you’ll need to set the class name to ‘png’.
<img class=”png” .. />

Tue, 3 Jun 08 04:58 am . Gerry Stanford wrote:

It appears that if you apply the png class to a tag that contains a png background image, then attempt to manipulate the position of the background image using hover and action pseudoclasses, the position of the image remains unchanged. I was attempting to slide navigation images from “off” to “on” positions using this technique. Know of any fixes, or how I might be misusing the code?

Tue, 3 Jun 08 10:23 am . Herryanto Siatono wrote:

Gerry, sadly, the position will be always be set to top left. And I’m not aware of any other solution out there that will still keep background position.

What I did usually, create the background image with the space required. Hope it helps.

Thu, 19 Jun 08 02:50 pm . Fin wrote:

On the code above, which are the parameters that we need to change? is that only blank.gif in the example above?

And I copy and paste the hack code into my css.
* html mydiv {/*The hack code is here*/}

Please advice on how to make this work for my div. Thanks

Thu, 19 Jun 08 02:28 pm . Herryanto Siatono wrote:

Fin, you don’t have to change anything, for your div, set “png” for the class name.”
<div class=’png’>…</div>

Thu, 19 Jun 08 02:35 pm . Fin wrote:

Here is my HTML:
…..

and I want ‘mydiv’ to has overflow and set the background image=repeat.

Thu, 19 Jun 08 02:41 pm . Herryanto Siatono wrote:

Fin, You may have missed the note above, this solution doesn’t work for for repeated/positioned background.

Wed, 25 Jun 08 07:37 am . Sambo wrote:

Doesn’t’ seem to work for rollovers…

Thu, 26 Jun 08 10:33 am . Nils Hendriks wrote:

@Herryanto Siatono:

I consider myself a developer as well.

And of course it may be put down to ‘preference’, but I don’t see a reason to put in all that extra code and work for what is essentially a hack for IE

Thu, 26 Jun 08 10:55 am . Nils Hendriks wrote:

hmm, my text was cut off!

my last line should have gone on like this:
“plus adding an extra class name (png) in HTML which isnt very semantic either…”

Wed, 2 Jul 08 01:42 am . Cosmi wrote:

Thanks, useful stuff.

Thu, 3 Jul 08 10:02 am . Anthony wrote:

Tried the fix script, looks great but my page now has broken tables and no links work whatsoever on the page…

plz help

Mon, 7 Jul 08 12:24 pm . Herryanto Siatono wrote:

Anthony, did you try the updated script (UPDATE 2), I’ve just removed the old reference to the previous script to avoid confusion.

Tue, 26 Aug 08 01:25 pm . PuneTech » Interview with Mayank Jain - Co-founder of ApnaBill.com wrote:

[…] Prototype javascript library solves a lot of common cross browser issues. To completely eradicate them, an additional PNG hack from Pluit Solutions and IE7.js which lets IE6 browser render PNG images which have transparency. Once you have sanity in terms of cross browser issues, you can actually start focussing on feature development. […]

Wed, 26 Nov 08 10:00 pm . Derrick wrote:

After trying literally dozens of junk scripts, this is the only one that worked fully for me. It works with PNG 32 and 8, for background images, and javascript rollovers.
Hats off to the developer. Somebody finally got it right.

Note: this worked on my positioned div background images as well.
WOW!

Wed, 26 Nov 08 10:22 pm . Derrick wrote:

One question however, is there a preferred doc type. Im using strict 1.0 XHTML 1.0.

Thanks

Thu, 9 Apr 09 01:40 am . steelfrog wrote:

This CSS unfortunately didn’t do the trick for me. It ended up cutting off half of the page (e.g., anything past the scroll bar) until I hovered on a block-level element.

Mon, 27 Apr 09 04:10 pm . VDV wrote:

Hi
this can bring BG of div bottom:

after:
this.runtimeStyle.backgroundImage = “none”

past(don`t forget put , after “none”):

img = new Image(),
img.src = this.origBg,
this.style.marginTop = this.style.posHeight - img.height,
this.style.height = img.height

Add Your Comment



(optional)