We’ve all seen them, the hoards of PNG fixes for IE6. That is because IE6 is a bag of smashed buttholes. I’m serious. It is. That is why we (web designers of the new world) have to continually come up with creative ways to solve the PNG issue. In case you are lost, just realize that in IE6, PNG images with transparency do not show their transparent regions, so you have to use some crazy IE6 proprietary filters. Moving on.

Lately, in projects I have been using a modified CSS snippet I found out on the interwebs to automagically replace PNG images with their AlphaImageLoader equivalent in IE6. Check this out here and I’ll explain and give an example:

The CSS/Code

* html img,
* html .png{
position:relative;
behavior: expression((this.runtimeStyle.behavior="none")&&(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 = "transparent.gif"):(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)
);
}
Update: This code changed to remove the behavior at runtime based on @Thierry’s suggestion.

For you purists out there, this is extremely hacky, so you may want to skip this whole entry entirely.

Update: : CSS Conditional comments for IE are a perfect way of hiding this hacky code from the good browsers. Here is a way to bring in the CSS for only IE 6 and below:

<!--[if lte IE 6]>
<link rel="stylesheet" type="text/css" href="png_fix.css" />
<![endif]-->

Ok, there won’t be much in the way of explanation here, but let me explain what this little bad-boy does.

The Selectors

* html img,
* html .png

The selector portion of the CSS rule targets which XHTML tags/classes this rule will be applied to. At first glance, it looks like all img tags as well as all tags with a class of "png". You’ll notice the (star) html in front of both of these. Wait, there is no “anytag” preceding the html tag, so this won’t get applied! True. For all non-crappy (that is a pro term by the way) browsers, this rule won’t get applied. However, since IE6 is a pile, it thinks that there is a tag before the html tag, so it will apply this rule. Great! Now IE6 is the only browser that will use this rule.

The Rest of the Code Jargon

Honestly, the rest you really don’t want to mess with much, but it suffices to say that this expression does a few things:

  • If the tag is an IMG tag, the expression checks to see if it is a .PNG image. If so, it applies a CSS AlphaImageLoader filter to the IMG tag to load the PNG file as a background image. It then points the src attribute of the image to a transparent gif so that the image isn’t overlaying it’s own background. Voila! Note: This only works well for images not resized by the browser. Also, you’ll need a transparent gif 1px by 1px image on your server.
  • If the tag is not an IMG tag, then this expression takes the CSS given background image and shoves it into a background AlphaImageLoader filter. It then removes the real CSS background-image rule so that the background and the filter are not conflicting.

Pretty cool! Please note that this CSS expression is pretty generic. If you have some crazy CSS-ing to do, you might want to stick with using your own methods or apply the AlphaImageLoader filter manually.

Also, if you are a standards-compliant junkie and this brushes you wrong, remember that this is intended to help with the crud of browsers. Sometimes we have to break our own rules to do the job.

A Demo!

Let’s see a demo! See the goodness below:

My Image Tag:

Twitterific Rules

My Generic Tag

Wish I could Play.

My Link Tag

Update: Links will need an additional rule of cursor: pointer; to restore the cursor. I’ll have to change that in the script to do that automatically

Comments

181 Comments

Pages:
  1. Kevin said 1351 days ago

    I see a lot of site but some of them don’t seem to work.

    So what is the most valid way of getting my PNG background image in css and PNG images on the page to work?

    Thanks.

  2. Rogie said 1352 days ago

    @Chris – Try to put another DIV tag around the form and give it a CSS position:relative;

  3. Chris said 1352 days ago

    I have a div tag that has a png as the background. I used this code to show its transparency, but on the page there is a form over the png. For some reason the form cannot be focused on, and there is also an email link which doesnt work either.

  4. Rogie said 1357 days ago

    @mae – Yeah, as long as they use an IMG tag or a class of “png”, you should be set. :)

  5. mae said 1357 days ago

    do you know if this will work in ruby on rails generated images?

  6. Png transparente con css | Cmacias.com said 1359 days ago

    [...] entonces cuando buscando el archivo, me encontré con un artículo en el cuál decían que se podia utilizar la transparencia del png sin necesidad de archivos [...]

  7. vitaly said 1360 days ago

    Nice! Thank you for your post.

  8. Nitesh said 1493 days ago

    Hey Dude
    This is brilliant.
    I am having one problem though:
    If I have nested divs and I apply the fix to the parent div, the content in the child div is somehow getting screwed up…!!

    I validated my html and everything seems fine there..

  9. EvanG said 1501 days ago

    oops sorry, you’ll have to replace the \’ with ‘ in my code.

  10. EvanG said 1502 days ago

    Sorry to comment twice, but I also found that on my website, only backgrounds set on “no-repeat” should be sized to “crop”, others should be “scale”, because I use 1px high images as background. So I modified the code in that purpose, it may help some people I guess. I have also addressed differently the issue I was talking about in my previous post, so it still supports the png class. Finally :

    * html img,
    * html .png {
    behavior: expression (
    (this.runtimeStyle.behavior=”none”) && (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/common/transp.gif”
    ) : 0
    ) : (
    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.currentStyle.backgroundRepeat != \’no-repeat\’) ? this.runtimeStyle.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\’” + this.origBg + “\’, sizingMethod=\’scale\’)” : 0,
    this.runtimeStyle.backgroundImage = “none”
    ), this.pngSet=true
    )
    )
    );
    }

    This css + giving 1px height to certain divs in IE6 (if no background appears at all, it means the div needs a 1px height) = everything works fine now (at least the best way that could be done) !

  11. EvanG said 1502 days ago

    Hello, as sb else said, this css solution is just perfect, it’s clean and also works on dynamically added content :D

    However, I come here to say that it caused bugs on a few GIF images that I had absolutely positionned. I don’t know why, but they were still here, but totally transparent. So I added something so the fix would only act on PNGs. The code I finally came up with :

    behavior: expression(
    !this.src.match(“png”) ? 0 : (
    this.p ? 0 : (
    ……
    this.p = 1
    )
    )
    );

    Thank you very much Riddle for the “p” trick !
    For background images I added the filter manually, just had to set a height and a width for IE6 only (1px).

  12. WebDrops said 1503 days ago

    One of the site effect of this solution seems to be an extra request to the server of the for “GET /none” PER IMAGE. If you have a large number of requests, this can be significant. Haven’t looked at the solution in detail to figure out a fix..has anyone else seen this?

  13. stevo said 1505 days ago

    great workaround.

    thanks a lot

  14. Tomas Hlustik said 1515 days ago

    PNG TRANSPARENCY IN STD MODE (INTERNET EXPLORER 6)

    If you are experiencing problems with this solution in IE’s “quirk mode” as I did (due to XML prolog on the first line of your XHTML code), try the above mentioned link:
    http://24ways.org/2007/supersleight-transparent-png-in-ie6

    This works flawlessly :).
    That’s why I don’t use this solution.

  15. Daan said 1515 days ago

    Okey, got it fixed now. Dont know how I did it since I did alot on it. So im very sorry for not being able to explain it.

    Just wanted to let you know :-)

  16. Daan said 1516 days ago

    Anyone? I can’t get it fixed. I even used position: relative in every a link. Meaning a:hover and such in my case.

    Still hoping for a little help.

    Greetz,
    Daan

  17. Sad Panda said 1518 days ago

    Follow-up!

    http://24ways.org/2007/supersleight-transparent-png-in-ie6

    A little bigger than the solution here, but it works.

  18. Sad Panda said 1518 days ago

    I, like a few others, do not have any success with this. I’m glad for all of you that have it working. I reduced things down to the simplest case and it still fails.

    transparent gif: check
    applied class .png to DIV: check
    css included in style tag: check
    made sure gif path in script was correct: check

    No love. Curiously, I tried several other solutions that people seem to have working, but none work for me at all.

    On another note, I came here with Firefox, but wanted to see if IE 6 works on your site here. Hitting this page in IE 6 crashes it hard. Now this could be( and the png problems as well ) because I am running IE 6 in Virtual PC, who knows? Microsoft products are utter garbage( I am typing this in Firefox on a rock-stable linux box ).

  19. Daan said 1518 days ago

    Hi there,

    great work on the hack. Been searching for something like this for a while. Here is my website where I am using your code. Im no pro or anything so u might see some bad coding (be warned).

    However the problem I have is that my links aint working anymore (in IE6 that is) Every other browser just sees my links like they should. Could u give me any help here?

    Link; http://www.onemind-designs.nl/_projecten/lsz/website

    Cheers,
    daan

  20. James said 1519 days ago

    Great ..thanks

    But small problem is there, if we want background-position:bottom; then its not possible in ie6. could u plz help me…

    hight is 300px image hight is 50px.. now i want image in bottom of the td… is it possible in ie6?

  21. Aadi said 1521 days ago

    Great article and thanks for the ideas. I had a 24 bit png image as a heading background and this solution didn’t work for me for some reason, so I used conditional comments and css rule in the conditional css file for IE:

    — THE CSS RULE —
    #inner h1{
    color:#fff;
    margin:0;
    padding:0;
    background-position:top center;
    background-color:transparent;
    background-repeat:no-repeat;
    background-image:url(../images/vts_title.png);
    text-indent:-9999px;
    }

    — CONDITIONAL RULE —

    — Conditional CSS rule in pngfix.css —
    #inner h1{ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’images/vts_title.png’, sizingMethod=’scale’);
    position:relative;
    width:556px;
    height:23px;
    }

    Setting the width and height fixed the issue in this case.
    Thanks very much ;)

  22. Barbara said 1522 days ago

    Another solution for the rollover problem can be a simple layer visibility exchange, like this (note that the layers are named “Layer1″ and “hiddenlogo”):

  23. Peter Velichkov said 1523 days ago

    as suggested for repeating there are not many possibilities, i tried scaling here – http://blog.creonfx.com/internet-explorer/ie6-png-transparency-css-background-repeat-fix

    also we may try flash, or repeating divs with javascript

    What do you think ?

  24. Elisa said 1523 days ago

    I’ve been struggling with IE and PNG just like the rest of you guys and this this has been the best implementation of the alphaImageLoader fix that I’ve seen. Easy and as clean as it can be in all it’s messyness ;)

    THANKS!

  25. Mark Abucayon said 1523 days ago

    I used it already and it works, it saves my day. Thanks

  26. Barbara said 1525 days ago

    Thank you so much! This was the simple solution I was looking for. So now we can only wait for the last IE6.- users to upgrade their software to give us webdesigners/developers some time to die our grayed hairs…
    http://stmap.beautifullalaland.com/index07-2.html

  27. Jeremy Anderson said 1525 days ago

    @Brie, the position: relative on the input fields should fix your form focus problem.

  28. Jeremy Anderson said 1525 days ago

    Forgive me if any of this has been addressed. I’ve been working quite a bit with AlphaImageLoader and these issues so I thought I would answer a few inquiries.

    First, the AlphaImageLoader filter does screw up links. Not always. It depends on the CSS properties assigned to the link. There is a fix that seems to work. If you assign a position: relative to the “a” tag it will usually fix it.

    Second, the AlphaImageLoader does allow for repeating background images or positioning background images within an element. However, for certain types of images, such as 1px by X, x or y repeats or 1px repeats, you can set the sizingMethod to scale. Scale will stretch the image to fit the defined area.

  29. Brie said 1525 days ago

    I have a form over a png background image that I can’t get to work – when this is applied there you can’t focus on the fields in IE6.

    I was able to get links over png background images to work just by adding position:relative, but that didn’t work for the form.

    Any ideas?

  30. David Westerdael said 1527 days ago

    This workedperfectly for me thanks for the help! In a few cases I decided it would just be easier to build a duplicate png as a gif image and call that when ie6 loaded, but otherwise where i really didn’t want to give up quality I kept my pngs.

    For all if you need a great way to use multiple versions IE’s there is a cool program I got yesterday. here is the link : http://tredosoft.com/Multiple_IE

  31. Joefrey Mahusay said 1528 days ago

    Thanks for sharing this wonderful css code. im gonna use this to my personal site. :)

  32. Santi said 1528 days ago

    GREAT FIX!!!!!!!!!!!!!!!!!!!!!!!!!

    the best that i saw.

  33. Shaun said 1531 days ago

    Sorry, that link should be to http://www.tarves.net/test

  34. Shaun said 1531 days ago

    Hi -

    Can someone please help me with this? I’ve got everything set up exactly (as far as I can tell) as it should be, but I still get the blue background. I’ve gotten it working putting the filter stuff inside a file tag for an image, but not in the stylesheet. I’m at a total loss. Check it out

    Thanks!

  35. Euan said 1533 days ago

    This fix is great, I’m so happy with it. However, like the poster above me, I think it would kick even more butt if it could be used with the sliding doors technique for rollovers in IE6. Has anyone managed to achieve this with a png graphic and successfully implement this fix at the same time?

    Thanks :)

  36. Rogie said 1536 days ago

    @Pix: Unfortunately, this won’t work with background-position in CSS. I haven’t seen IE’s ability to background position a filter…you are probably going to have to get really tricky with your CSS to pull that off.

    @Anders: I just tested it in IE6 and I cannot see the alt text next to the image. Are you sure you uploaded the transparent.gif file and it’s path is correct in the CSS?

  37. Pix said 1536 days ago

    Thanks a lot! this tecnique works great but i’m having some trouble with png that need to be “rollovered”.
    in fact, if you have something like this

    a:hover { background: url(something.png) no-repeat bottom center;}

    this “fix” kills all the background position rule…
    any suggestion to avoid this?

  38. wzberger said 1538 days ago

    Unfortunately the W3C CSS validator recognizes some errors…

  39. Anders said 1538 days ago

    Hey Rogie! Thanks for this great tutorial. One question though.. How come IE6 shows the alt-tag next to the image? Is there some way to prevent this without removing the alt-tag? I kinda want it to validate. :)

    Thanks again.

  40. danielpunt said 1539 days ago

    It works great, but the background images are positioned in the upper left corner, while they were centered or positioned right in the original CSS.

  41. Whatever-ishere said 1541 days ago

    thanks for the GREAT post! Very useful…

  42. Gregori said 1541 days ago

    Hi!
    I finished the translation of your article for the Portuguese language. Thanks for the permission.

    If you want to see:
    PNG Image Fix for IE (pt-br)

  43. Rogie said 1541 days ago

    @phoose: “lte” stands for “less than OR equal to”, so in the case of “if lte IE6″, the code will work on all Explorer browsers less than or equal to IE6 that support conditional comments of course.

  44. phoose said 1542 days ago

    Shouldn’t the conditional comment target IE6 and below as opposed to the above which only targets below IE6?

    IE: if lte IE 7

  45. Rogie said 1542 days ago

    @Tom: You got it right. Stickin’ it to the IE6 users.

  46. Wouter de Bie said 1542 days ago

    Great stuff! Thank you very much!

  47. Tom Hooper said 1542 days ago

    As it’s replacing the foreground image with a transparent gif, I assume Right-Click > Save Image As.. won’t work?

  48. E11 said 1544 days ago

    Hi there,
    Thanks for the fix. I was using a Javascript fix (http://homepage.ntlworld.com/bobosola/pngtestfixed.htm) that worked similarly except you had to assign a width for all images which is fine until you start using background images.
    Both worked except for the top and bottom background images as shown here (http://www.e11world.com/pngfix.jpg)
    Can anyone tell me what I’m doing wrong?? Original page files are here (http://www.e11world.com/interactive/)

Sorry, the comment form is closed at this time.