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. Peter said 2012 days ago

    np – frameworks save me a lot of time because i use it for couple of others scripts and not using a framework would cost me the same bandwidth penalty

    Cheers

  2. Luke Veach said 2013 days ago

    Rogie: Thanks much for the excellent examples and explanation (forgot to mention that in my comments above)!

  3. Rogie said 2013 days ago

    @Peter: Great work. For those that want to use a JavaScript framework, that is bomb.

  4. Justin said 2013 days ago

    Sorry, should have read all the posts in here first!!! Got it to work using Anna Vester’s code. Thanks.

  5. Justin said 2013 days ago

    This is a great bit of coding!!!!

    I hope someone could adapt it to make it work for repeated background images though, then it would be a killer script!!! Mainly for helping with background image borders that go from a colour to transparent where you can only use a png image.

  6. Peter Velichkov said 2013 days ago

    you may find my version more advanced (also it was refactored by CNET.com javascript developer)
    http://blog.creonfx.com/internet-explorer/ie6-png-transparency-fix-javascript
    or the refactored version
    http://blog.creonfx.com/internet-explorer/ie6-png-transparency-fix-with-javascript-v20

  7. Luke Veach said 2014 days ago

    @Riddle:
    your example pages are excellent.

    I took a look at the studio page link and was noticing that IE was downloading the button PNG everytime the background image shifted colors, is this just a caching issue on my side?

  8. Jeremy Aldrich said 2014 days ago

    This is so cool. I have always disliked the png fixes for ie 6 and therefore never used them. But now that i have a fix that takes place through the css and fixes background images, i might rethink that. Many thanks for this ingenious fix. Just so happens that i came across this site at the same time that i inherited a site built by someone who didn’t know png’s didn’t work in 6. You saved me a lot of headache. Thanks again.

  9. Rogie said 2014 days ago

    @Thierry: This is just the sort of thing I love to get comments back on. Let me see if I can implement the changes and modify this entry to reflect your changes.

  10. Jermayn Parker said 2014 days ago

    Kewl! First time I have seen your blog and so a good start with a very good article on this buggy IE! The best solution however would be a mass assassination of all IE6 but alas I doubt it :(

  11. Geekstr said 2014 days ago

    “That is because IE6 is a bag of smashed buttholes”

    LMFAO! I almost shot Diet Coke out my nose on that one!

  12. Thierry said 2015 days ago

    Riddle: but that’s the whole point, as making IE thinks more is not really a good thing.

    Anyway, looking at this example, why not going with “behavior” rather than “azimuth”?
    * html .png {
    behavior:expression((this.runtimeStyle.behavior="none")&&(/* the stuff goes here */))
    }

    this.runtimeStyle.behavior="none"
    Should make sure it is ran only once.

  13. akella said 2016 days ago

    AFAIK dropping “this.” where it is possible will make expressions 1-2 times faster.
    just my 2c

  14. Riddle said 2016 days ago

    Thierry: You make IE think more when you hover a link than this small condition based on expando. :)

  15. Thierry said 2016 days ago

    @Riddle: How many times this.p is evaluated?

  16. Nick said 2016 days ago

    Bravo! I’ll be using this on my next project.

    Beautiful footer for this comments box by the way.

    As for links within a container with this fix applied, you can give them “zoom: 1″ or “position: relative” to trigger hasLayout and they should work.

  17. Riddle said 2016 days ago

    Thierry: They’re not if you know how to use them.

    Calculating height for element can and should be done real-time, without any checks, but if you simply replace elements or add new content, you should do this:

    jscript: expression(
    this.p ? 0 : (
    //your code here,
    this.p = 1
    )
    );

    This way code gets executed only once. I’ve been using them for a looong time and I haven’t encountered any problems.

    Rogie, let me be an attention ho and link to my fixes for adv CSS. ;-)

    And one more, I finished it yesterday. Believe or not, but this splash page looks the same in IE6, thanks to expression(). :)

    One day IE6 will be banished to the fires of Mount Doom as it should. For now it will just infect us and make us weaker.

    This is soo true. Do any of you nay-sayers know that IE7 supports first-child, advanced selectors, transparent PNGs and has all the Position is Everything bugs squashed?

    Whereas I need 10KB of hacks for my site to look the same in IE6, I only need 1 for IE7 (usually Generated Content, which I’m using for some time to clear floats).

    Expression() FTW, we can’t live in the Stone Age forever.

  18. Jasper said 2016 days ago

    I’m working on a website with a lot of png. This hack is beautifull. But i’ve seen to run in to a problem. For a specific object I overrule the standard background png defined before, to this I need to use “!important” on my background value in css (talking about a background on a div). But when I use “!important” the hack doesn’t work for that object. Now I’m going to try to figure out anther work around, but maby some of you readers have already got the solution? Many thanks, Jasper – mediaCT

  19. Rogie said 2016 days ago

    @Theirry: I totally agree. So you have 2 solutions:

    1: Hand code filters for PNG transparency.

    2. Recode the core of IE6 to make it NOT crap.

    Enjoy.

  20. Thierry said 2016 days ago

    CSS expressions are evil ;-)

    http://developer.yahoo.com/performance/rules.html#css_expressions

  21. Confluence: Site Design said 2016 days ago

    Some links for light reading – November 13th, 2007…

    Semantify, and CSS tools based on Blueprint…

  22. akella said 2016 days ago

    really nice hacky code!

    But did you think about productivity of the script? As you might know expression will be calculated on each action on a page(click, resize, hover), not so good when you got dozen of them.
    And actually there is a way to execute it once on load. I’m just not sure weather your code taking it into account or not?

  23. Rogie said 2016 days ago

    @Luke: crap! azimuth….ok, lets choose a rule that doesn’t hinder anyone.

    @Bjarne: Word. Maybe a rule of * html img.png would suit better. That way this script only works on images with a class of “png”.

    @Anna: Very smart of you. However, scale will only work in one axis only, so if you need to repeat-x or repeat-y, you are golden, however if you need to actually repeat as in tile, I guess you are out of luck ;)

  24. Anna Vester said 2016 days ago

    Rogie, nice one here. I have tweaked your code a little bit and it now works in IE6 with repeated background images. All you need to do is to change crop to scale. It works like magic!

    I wrote about this addition to your png fix in my blog.

    Regards.

  25. Bill said 2017 days ago

    Anyone who is having trouble with using PNGs in links on IE6 needs to avoid having the links absolutely positioned. For some reason IE6 will not let you click on a PNG background image when it’s absolutely positioned. I believe there is a way to fiddle with the z-index and trigger hasLayout in order to fix it. I can’t remember the details offhand, but doing a search for “absolutely positioned PNGs in IE6″ should give you some more info.

  26. Bjarne J said 2017 days ago

    Hi there

    A really clever attempt to “crack” the IE png-problem.

    One thing that bothers me…what about the performance ?. Normally expressions in CSS are really performance-heavy, and your solution “connects” directly to all img-elements in the DOM !

    Cheers

    BJ

  27. Jerry said 2017 days ago

    A “bag of smashed buttholes”? Classic!

  28. Luke said 2017 days ago

    Who knew? I could have sworn that azimuth property had something to do with accessibility for the deaf! This works very nicely btw :) and I added a js file that automatically adss the .png class to png images to ease it up a bit.

    Good job!

  29. Rogie said 2017 days ago

    @Simon: Sure, add some css to make it absolutely positioned, or better yet absolutely positioned within a relatively positioned header. Then apply add the rules bottom:0; right:0; That’s it!

  30. Simon said 2017 days ago

    Hi
    I would like to use this for a white logo on different coloured backgrounds. It needs to be positioned on the right hand side of my header using css. Will it position bottom right? Thanks

  31. Rogie said 2017 days ago

    @Tom H: Tom, be sure that you have the transparent.gif image uploaded to your server and that the path to it is correct.

  32. Tom H said 2018 days ago

    Hi, I tried this method but Im having the problem where it displays the png correctly, but over the top of that has the non-loaded image box with a red x. Any ideas? Many Thanks

  33. Rogie said 2019 days ago

    @Chris: The trick should work as a link, in fact I will update this post to show a link, however it is a known glitch that in IE6 any child link tag within a AlphaImageLoader filtered tag will be rendered useless. That is to say, you got a link in any tag that has an AlphaImageLoader filter, it will NOT work. However, It may work when applied with JavaScript.

  34. Chris Basey said 2020 days ago

    Great trick – however it doesn’t seem to work if the background image is a link. Or rather – the technique works, but the image isn’t linked anymore.
    I am using background images for navigation – using image replacement, and while the transparency works like a charm they’re not clickable now
    Is there a way round this?

  35. bob said 2020 days ago

    Nice article with great solution to this problem. Otherwise users have to shift to .GIF but unfortunately they don’t support 24bit colors and alpha transparencies.

  36. Riccardo Giuntoli said 2020 days ago

    Nice article. Finally a good solution to the PNG problem in IE6.
    Thank u!!!

  37. Rogie said 2021 days ago

    @Neil: Unfortunately, repeating background images doesn’t work with this technique. Man, I wish it did!

    @Christoph: Hmm, I can’t seem to replicate your screenshot. Are you running multiple versions of IE?

  38. Neil said 2021 days ago

    Does this work with repeated background images? (Something that has also been missing from other techniques).

  39. Christoph said 2021 days ago

    It’s not working in IE6. Lock at the screenshot: http://www.cgdesign.de/screen.gif

  40. Franck said 2021 days ago

    Great ! That is THE technic to fix PNG transparency.
    Thanks a lot.

  41. zoel said 2021 days ago

    must be used “/style/images/transparent.gif”? ……

  42. Rogie said 2021 days ago

    @All: Word to your mother on gettin’ rid of these hacks. One day IE6 will be banished to the fires of Mount Doom as it should. For now it will just infect us and make us weaker.

    @Jeff: Dude, tell me what’s going on or link me. I’d love to help you out on this issue. Maybe it’s a wee glitch in this script…

  43. Mike said 2021 days ago

    @Bill: You should be able to fix conditional comments using the methods over at PIE – they’ve always done the trick for me.

    Great tip for fixing PNGs. I long for the day when we won’t have to use these hacks any more ;)

  44. Bill said 2021 days ago

    BTW, If you have IE7 installed as your default IE, but you have a copy of IE6 running as a standalone for testing, your standalone install of IE6 will think that it is IE7 when it looks at the conditional comments. You’ll want to test the CSS out without the conditional comments to make sure it’s working. Then add the conditional comments back in so that it never interferes with good browsers.

  45. Jeff Byrnes said 2021 days ago

    Hmmm…tried it on my site, doesn’t seem to be working. Not sure what I missed, perhaps you can take a peek & point me in the right direction?

  46. Kerwin said 2022 days ago

    I’ve read the same on some other blog, but it was getting way more into the scripting side.
    Thkx for making it a lot more easier to understand, it’s such a shame nobody thougt of this a few years ago…

  47. Jasper said 2022 days ago

    don’t care if it’s hacky – if it works where it’s supposed to, that’s all I care about. I shall banish it to the depths of my IE6 CSS file in the morning! many thanks for this – I’ve just been looking for this very solution!

  48. Rogie said 2022 days ago

    Great suggestion @Bill. I have updated the tutorial to reflect your additions :)

  49. Bill said 2022 days ago

    Actually the conditional comments worked so well in my example above, you can’t even see them. But, you get the idea.

  50. Bill said 2022 days ago

    I like it. Except the CSS won’t validate (or as you say, it’s hacky).

    I think it would be much better to use “conditional comments” so that only IE6 will see it.

    Conditional comments are ideal because they are real W3C-compliant comments that only IE6 chooses to read. So, you get the best of both worlds. I would do something like this:


    @import "/png-fix.css";

    and put all of the hacky stuff inito png-fix.css.

Sorry, the comment form is closed at this time.