A Better IE6 PNG fix

I’ve been working with Pngs over the last few weeks because they just look so much dang better. But then I went to setup IE6 support and some of my quick-hacks I used. If you’re not aware, to use transparent pngs in IE6 you need to set them as the background of say a <div> or <span> and then apply a filter to it. If we were to apply it in css it would look like this:

.myPng{
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='/images/mysweet.png');
}

However, to use only css to do this we _need_ to know the height and width of the image, because the filter actually just sets the background image. There’s a few other png hacks out there but none that really worked for me for various reasons. What I needed was something that was fast, lightweight, easy to read, and I could call it if I was building an <img> tag in javascript. So I made this:


Global = {
FixPng: function( img ){
if(document.all){
img.parentNode.style.width = img.offsetWidth;
img.parentNode.style.height = img.offsetHeight;
img.parentNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='"+ img.src +"')"
} else {
img.style.visibility = "visible"
}
}
}

The only catch is that this relies on three things:

1. The <img> tag must have style=”visibility:hidden”
2. There must be a <div> tag wrapping the <img> tag. (the <div> tag can have styling)
3. The FixPng is called at some point passing the <img> tag object

So a normal fix would look like this:


<div><img src="/images/mysweet.png" style="visibility:hidden;" OnLoad="Global.FixPng( this );" /></div>

That’s about it. I don’t think this is my last iteration of this fix, but it works 100% better for me since I can easily use this in html and in javascript. I hope it helps you.

note: I’ve heard that the <img> OnLoad doesn’t always fire in IE6 because of caching. There’s workarounds, but if you have any insight, please post.

25 thoughts on “A Better IE6 PNG fix

  1. ¡Hey! ¡Good script!

    The only place where i can make an observation is the use of document.all to catch an IE.

  2. Hey what about the PNG images coming through css..is there any fix..this fix is not useful though as most of the background effects comes through css only

  3. When i copied the Global object-code it came with “ insted of ” and ’ insted of ‘ etc etc.
    Result=error.

    Heres the code with right types of quotes (I hope):

    Global = {
    FixPng: function( img ){
    if(document.all){
    img.parentNode.style.width = img.offsetWidth;
    img.parentNode.style.height = img.offsetHeight;
    img.parentNode.style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='”+ img.src +”‘)”
    } else {
    img.style.visibility = “visible”
    }
    }
    }

  4. Ignore my previous 😉
    I guess your replacing ‘ and ” to remove sql-inj or whatnot.
    But you should inform viewers of this, anyone not very good at js will bugg his brain out.

  5. BEST FIX…I’ve been looking for one for ages, had a lot of trouble implementing other fixes. This is great, nice one 😛

  6. @Claudiu

    I’ve found that it’s much easier to just handle the roll-overs in a stylesheet. Giving the element a class or id then switching the filter for it on :hover. Instead of using javascript to auto-replace the background with a filter. I hope that helps.

  7. Thanks, this is great.
    I had problem with links on hover… using this solution I was able to make it work:

    #topmodulestable .topmodulestd .generalbtn a, #content3coltable .content3coltd .generalbtn a, #botmodulestable .botmodulestd .generalbtn a{
    background-image:none;
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src=’img/btn_bg.png’);
    cursor:pointer;
    }
    #topmodulestable .topmodulestd .generalbtn a:hover, #content3coltable .content3coltd .generalbtn a:hover, #botmodulestable .botmodulestd .generalbtn a:hover{
    background-image:none;
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src=’img/btn_over_bg.png’);
    cursor:pointer;
    }

    I added “cursor:pointer;” to the style as it seems to be needed for the pointer mouse icon.

  8. Hi,

    I am facing a wierd problem with IE6. The issue is as follows.

    I have many div tags in my web page (popup). One of the div has a table with 3 rows. The 1st row has a label, 2nd row has data that the user can provide (something like editor control) and the 3rd row has link. when the user enters large data in the editor control and save it its getting saved and everything is perfectly fine. The problem comes when the user opens the web page. The UI is scattered because the 2nd row exceeds and the div tag gets expanded and hides the link button. This issue is only in IE6.

    Can you please help me or direct me so that i can resolve it?

    Thanks in advance.

  9. To not have the cache problem, i adapted the script to this:

    function ie6PngFix(arr) {
    for (var i = 0; i < arr.length; i++) {
    img = document.getElementById(arr[i]);
    if (document.all){
    img.parentNode.style.width = img.offsetWidth;
    img.parentNode.style.height = img.offsetHeight;
    img.parentNode.style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='” + img.src + “‘)”
    } else {
    img.style.visibility = ‘visible’;
    }
    }
    }

  10. It works if you write :
    ‘progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=\’scale\’, src=\”+ fichier + ‘\’)

    Notice the comma behind “sizingMethod’ and the ‘ around.

    And you’ve forgotten the units : px

    Here a method to add the div :
    var parent=img.parentNode;
    var tailleX=img.offsetWidth, tailleY=img.offsetHeight;
    var fichier=img.src;

    parent.innerHTML=” + parent.innerHTML + ”;
    img=parent.childNodes[0].childNodes[0];
    var nouvParent=obj(parent.childNodes[0]);

    nouvParent.style.width = img.offsetWidth +’px’;
    nouvParent.style.height = img.offsetHeight +’px;

    img.style.background=’none’;
    img.style.visibility=’hidden’;

    nouvParent.style.filter = ‘progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=\’scale\’, src=\”+ fichier + ‘\’)’;

  11. Hello Guyz, Here is my Fix to this problem!

    Download jQuery-Plugin “pngFix” from (http://jquery.andreaseberhard.de) Great PlugIn By The Way!!!

    –Change these lines like the following:

    // this line
    jQuery(this).find(“img[src$=.png]:visible”).each(function() {
    // this line
    jQuery(this).find(“:visible”).each(function(){
    // and this line
    jQuery(this).find(“input[src$=.png]:visible”).each(function() {
    –Before the end Place this Code

    // Store a reference to the original method.
    var _show = jQuery.fn.show;

    // Overriding Show method.
    jQuery.fn.show = function(){
    // Execute the original method.
    _show.apply( this, arguments );
    // Fix Png
    return $(this).pngFix();
    }

    //No more problems with hidden images

    })(jQuery);

    //The End

  12. Great tiny fix!

    I’d add the visibility=”hidden” to the JS. Just to make sure.

    Global = {FixPng: function( img ){if(document.all){
    img.style.visibility=”hidden”;
    img.parentNode.style.width = img.offsetWidth; img.parentNode.style.height = img.offsetHeight; img.parentNode.style.filter = “progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='”+ img.src +”‘)”
    } else {img.style.visibility = “visible”}}}

    And then on the img tag, just write:

Comments are closed.