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 over 2 years 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 over 2 years ago

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

  3. Chris said over 2 years 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. » CSS Collection 2008 CSS Concept: CSS can be just that easy.. said over 2 years ago

    [...] CSS PNG [...]

  5. Rogie said over 2 years ago

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

  6. mae said over 2 years ago

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

  7. Png transparente con css | Cmacias.com said over 2 years 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 [...]

  8. vitaly said over 2 years ago

    Nice! Thank you for your post.

  9. Nitesh said over 2 years 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..

  10. EvanG said over 2 years ago

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

  11. EvanG said over 2 years 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) !

  12. EvanG said over 2 years 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).

  13. WebDrops said over 2 years 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?

  14. stevo said over 2 years ago

    great workaround.

    thanks a lot

  15. Tomas Hlustik said over 2 years 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.

  16. Daan said over 2 years 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 :-)

  17. Daan said over 2 years 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

  18. Sad Panda said over 2 years ago

    Follow-up!

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

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

  19. Sad Panda said over 2 years 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 ).

  20. Daan said over 2 years 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

  21. James said over 2 years 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?

  22. Aadi said over 2 years 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 ;)

  23. Barbara said over 2 years 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”):

  24. Peter Velichkov said over 2 years 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 ?

  25. Elisa said over 2 years 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!

  26. Mark Abucayon said over 2 years ago

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

  27. Barbara said over 2 years 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

  28. Jeremy Anderson said over 2 years ago

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

  29. Jeremy Anderson said over 2 years 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.

  30. Brie said over 2 years 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?

  31. David Westerdael said over 2 years 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

  32. Joefrey Mahusay said over 2 years ago

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

  33. Santi said over 2 years ago

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

    the best that i saw.

  34. Shaun said over 2 years ago

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

  35. Shaun said over 2 years 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!

  36. Euan said over 2 years 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 :)

  37. Rogie said over 2 years 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?

  38. Pix said over 2 years 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?

  39. wzberger said over 2 years ago

    Unfortunately the W3C CSS validator recognizes some errors…

  40. Anders said over 2 years 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.

  41. danielpunt said over 2 years 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.

  42. Whatever-ishere said over 2 years ago

    thanks for the GREAT post! Very useful…

  43. Gregori said over 2 years 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)

  44. Rogie said over 2 years 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.

  45. phoose said over 2 years 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

  46. Rogie said over 2 years ago

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

  47. Wouter de Bie said over 2 years ago

    Great stuff! Thank you very much!

  48. Tom Hooper said over 2 years ago

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

  49. E11 said over 2 years 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.