PNG Fix

November 26th, 2007

A quick, lightweight fix for IE PNG transparency support

The PNG Fix jQuery plug-in was developed to create a quick-and-easy fix for the PNG transparency issue in Internet Explorer 6. As it utilizes the jQuery framework, support is restricted to IE 6. At some point I will develop a stand-alone version, but for speed and efficiency a jQuery plug-in solution is hard to beat. With thanks to Angus Turnbull for Twin Helix’s original fix.

Update:

  • 1.1 - Updated example HTML and removed deprecated repeat value for the repeatMethod option
  • 1.2 - Fixed regex match error and revised sizing methods

Please note, repeatable backgrounds aren’t supported by the AlphaImageFilter (which this plug-in uses to render the graphics). You must either choose to crop the image into the size of the DOM element (default option) or scale/stretch the image to the size of the applied element.

Background positions are also redundant when using the fix as AlphaImageFilter only renders from the top left corner of the element.

Download Javascript source file (jquery.pngfix.js 8kb) or example pack (.zip)

Examples

To apply the fix to all images within the page:

jQuery(function($) {
     $("img").pngfix();
});

A more efficient approach would be to apply it to all image elements that reference PNGs, or directly via IDs.

jQuery(function($) {
    $("img[@src$=png], #image-one, #image-two").pngfix();
});

Options

There are currently two options for this plug-in:

repeatMethod
Choose between the three options for background scaling (inline with the MSDN guidance for the AlphaLoader filter.
  • Crop: renders the image at initial size.
  • Scale: stretches the image to the size of applied element.

Download Javascript source file (jquery.pngfix.js 8kb) or example pack (.zip)

Comments

Hello there! I stumbled upon your site looking for a solution to the google maps and IE6 PNG problem. I’m using a joomla template from Rocket Themes that uses a great deal of transparent images, so I need to keep transparency, but I’d also like to use Google maps.

I know basically nothing about Javascript….I do know that I’m using mootools in several places and that that can be a conflict. Found a page here that gives some information about getting around it (basically using something other than $ as a shortcut:

http://docs.jquery.com/Using_jQuery_with_Other_Libraries

Any help on implementing this would be greatly appreciated.

Thanks.

From Stephen Moseley December 31st, 2007 at 3:57 pm

So I just tried opening the example file on my local server (Joomla Standalone server) and it gave me the “active X” crap….I have mootools running on sites and IE doesn’t complain….is there something I would need to make sure to do to avoid that?

Thanks

From Stephen Moseley December 31st, 2007 at 4:35 pm

Stephen,

To prevent framework conflicts you’ll need to call the noConflict() method on the core jQuery object. Convenientaly it’ll passes back the object so you can instantiate jQuery into another variable, via which you can call all the standard methods - and in this case the PNG fix.

var $j = jQuery.noConflict();
$j(document).ready(function(){
    $("img").pngfix();
});

From Paul Campbell January 2nd, 2008 at 2:40 am

Hi Paul - promising sounding fix! I’ve just tried to implement it using your basic example but the PNG doesn’t appear to be affected - I’m still left with the ugly grey background. Does the PNG have to be in a certain format for this to work? The bg is definitely set as transparent already as it works in FF and IE7 :D

My code (for reference) was just:

$(”#logo”).pngfix();

Using jQuery 1.2.1 packed.

From Dave January 2nd, 2008 at 5:59 am

Dave,

Please download the example ZIP again, as i’ve made a fix which related to the doctype declaration and the IE javascript processor. This should fix the problem you were experiencing.

If you’re going to embed the code into a XHTML 1.0+ page then ensure you add either comments or CDATA nodes within the <script> tag (otherwise the page wont process corrrectly. Check out this link for more info.

From Paul Campbell January 2nd, 2008 at 8:57 am

Paul,

I’m trying to get the example working with the code you provided and I can’t seem to get it working. I’m sure that I’m messing up somewhere.

Is there anywhere else I need to substitute the “$j” for the “$” ? Do I need to replace anything in the actual javascript file? Sorry I’m quite ignorant about Javascript right now, but I’d love to get this working so I can use Google maps. Thanks so much for your help, and happy new year….

Steve

From Stephen Moseley January 2nd, 2008 at 11:28 am

Nevermind :) I needed to put in a $j on the following line:

$j(”img[@src$=png], #container”).pngfix();

From Stephen Moseley January 2nd, 2008 at 11:31 am

So I tried it out on the local server of my site and get a “done, but with errors” in IE6…

here is what I have:

/templates/getTemplate(); ?>/css/template_ie6.php” rel=”stylesheet” type=”text/css” />

var $j = jquery.noConflict();
$j(document).ready(function() {
$j(”img[@src$=png], #container”).pngfix();
});

The template_ie6.php file is a file that uses the alpha filters for a few images that were background images….I guess the .htc file couldn’t change those…

The error I get is:

‘jQuery’ is undefined

and the line corresponds to the follow line above:

var $j = jquery.noConflict();

I am I incorrectly referencing the jquery library?

Thanks for your help….

Steve

From Stephen Moseley January 2nd, 2008 at 11:58 am

Ok, sorry to be posting so much… I worked out the undefined issue…the path to the files were wrong. Thanks again for the fix.

Steve

From Stephen Moseley January 2nd, 2008 at 12:37 pm

No worries Steve. Glad to hear you fixed the problem! Please do let me know if you have any more issues getting the fix working with Google Maps, as I’m very keen to get the plug-in completely stable. Coincidentally the reason I ended writing the plug-in in the first place was to deal with a Google Maps mashup bug in IE!

Good luck!

From Paul Campbell January 2nd, 2008 at 1:27 pm

Paul,

Thanks for the fix! It turned out to be the version of IE6 I was testing in being the culprit as your example files don’t work in it wither. Not surprised though as it’s a standalone version of the browser that clearly doesn’t work as well as if it were installed properly.

Of course, IE6 and “working well” don’t go together in the same sentence so who am I trying to kid :D

Thanks again - great plugin!

Dave

From Dave January 3rd, 2008 at 5:05 am

Hey, great tool!

It’s mostly working for me, except some of my PNGs are getting rescaled. I can’t troubleshoot it well because some of my PNG images work fine. I am manually setting the image height and width attributes, and still have the problem. It only appears to affect the height.

From Acrobatic January 4th, 2008 at 4:28 pm

Are they all inline images via the markup or background images via CSS? If they’re inline images you may want to pass an option to set the repeatMethod to crop (as the default is scale). This will prevent resizing and just show the image “as is”.

To do this, you need to pass an option object into the plug-in function call as such:

$("#element-id").pngfix( { repeatMethod: "crop" } );

From Paul Campbell January 5th, 2008 at 5:03 am

They are inline images and I’m able to get them working now, thank you for the tip.

From Acrobatic January 5th, 2008 at 8:04 am

Is this the same as http://jquery.andreaseberhard.de/pngFix/jquery.pngFix.js? The copyirghts are different, but they look very similar (name, API calls, etc, haven’t compared code …).

From kulfi January 10th, 2008 at 2:12 pm

They share the same plug-in name but are quite different under the hood.

From Paul Campbell January 10th, 2008 at 2:37 pm

great plugin… but your site’s color scheme is litteraly painful to the eyes… I had to copy paste and read it in my text editor… Not trying to be mean, just giving you the heads up… After all, a blog is meant to be read :)

From yann January 12th, 2008 at 6:05 pm

So, I’m dealing with the Google Maps prob. I’ve been able to get my PNGs to render correctly, but it stalls/halts the loading of the Google Map. I haven’t started troubleshooting the issue yet - just wanted to let you know tho. But, thanks for the plug-in.

Kit

From Kit Plummer January 13th, 2008 at 4:28 pm

Haha, thanks Yann. I like to refer to it as “bleeding edge” design ;). I’ll take your comments into consideration though.

From Paul Campbell January 14th, 2008 at 2:07 pm

Can you plugin deal with remote?

$.ajax({
url: $(event.target).attr(’href’),
success: function(html){
$(’#wrapper’).after(html);
$(”img[@src$=png], #blueprint”).pngfix();
$(’#blueprint’).show();
}
});

I cant get that working.

From Andy Frost January 19th, 2008 at 3:24 am

@yann: I think you meant to say, “…a blog is meant to be red.” :P

From Paul January 22nd, 2008 at 2:26 pm

how would go about handling background images with this plug-in?

From ryan February 1st, 2008 at 3:05 am

Sorry, i should’ve just downloaded it… thanks… you can delete my comments if you want

From ryan February 1st, 2008 at 3:39 am

In order to make this work with IE6 I had to change if(matches.length) to if(matches&&matches.length)

From Woodrow February 26th, 2008 at 12:23 pm

I had to add one other hack, to make an element with a no-repeat background image work:

Change indexOf("repeat") > -1 to indexOf("repeat-") > -1.

From Woodrow March 3rd, 2008 at 8:31 am

Hi, this looks like it would be very useful, and seems to make my PNGs transparent in IE 6, but I’ve experienced a few issues - enough to disable this plugin for now:
1) transparency reappears on hover (when image is a link)
2) CSS rules seem to be lost (specifically, cursor: pointer, cursor: hand)
3) makes some of my PNGs simply disappear!
Now, all of these relate to PNGs wrapped in -a- tags (used as links), so I think that my be the crux of the problem…

From Sean O March 7th, 2008 at 7:02 am

I am thinking about implementing this fix, but was wondering if png images could have links? I have been using sleight so far and know that there is a problem with this and links. Thanks!

From amanda April 14th, 2008 at 4:05 pm

Paul, when i apply the fix to a div that has a transparent .png as a background, any images inside the div will not appear.

Is there a solution for this?

From Ryan May 6th, 2008 at 11:11 am

Paul, white text on a red background? I needed to change your CSS with firebug to read your site!

-Erik

From Erik Bruchez May 12th, 2008 at 4:54 pm

Hi Paul,

Thanks a million for this excellent plugin. I managed to get my client’s website up and running in IE6 in no time because of it. However, it seems that when I apply the fix every now and then links surrounding a .png image get disabled somehow. My client would really like to see this fixed asap. Problem is that I don’t have the slightest idea what’s causing it and how to fix it. Maybe I’m doing something wrong. I tried applying the fix to the links themselves, wrap each of them in a separate div, but so far - nothing.
I’m hoping perhaps you can shed some light on this? I’d really appreciate it.

My client’s website: http://www.fotoprofile.nl

Notice how the images/links (’America’s Next Top Model’ etc.) in the ‘Highlights’-panel on the right side are clickable in FF & IE7, but not in IE6.

I’m using jQuery v1.2.3 and the various .png fixes are applied as follows:

$(”table td”).pngfix();

// Fix background images on all A elements
$(”a”).pngfix();

$(”#primary_c1_img”).pngfix({
sizingMethod: “scale”
});

$(”#prim_c1_separator”).pngfix();
$(”#primary_c3″).pngfix();
$(”#hl_item1d, #hl_item2d, #hl_item3d, #hl_item4d”).pngfix({
sizingMethod: “scale”
});

// Fix all inline PNG images and the element #container with the custom sizingMethod of “scale”
$(”img[@src$=png], #navigation_branding, #wrapper_bar, #wrapper_bar_headliner, #wrapper_bar_img, #wrapper_primary, #primary_c1″).pngfix({
sizingMethod: “scale”
});

Thanks a lot!

From Dj May 15th, 2008 at 4:16 pm

Hi Dj,
Just looking briefly at your problem I suspect the issue is arising from the #primary_c3 fix. The fix has to set all internal <a> to position:relative; in combat the peek-a-boo bug in IE. I think this is probably conflicting with some of your current style rules and most likely removing the height on the <a> elements in IE. Try debugging with:

#primary_c3 a {
    border:red;
    display:block;
    height:xxx;
    width:xxx;
}

From Paul Campbell May 16th, 2008 at 1:15 am

Hi Paul,

Thanks for your quick reply. I’m terribly sorry to bug you right before the start of the weekend, but man, this thing is really driving me around the bend. IE6’s behaviour’s so inconsistent sometimes it’s freaking me out.
I tried to tinker around a bit with your suggestion and you were right - somehow the #primary_c3 div/fix is responsible for ‘collapsing’ all inner links , not to mention this annoying headache.
As you can see in the example below I’ve tried lots of things - create or drop wrappers, mess about with z-indexes, heights, widths and what have you. But I haven’t had much luck yet.

So I’d really appreciate it if you could have another go at this when you have time. Thanks in advance and cheers, Paul!

http://www.xaxu.nl/clients/fotoprofile/website/test.php

p.s.: in case you come up with something really clever - next time you’re in Rotterdam drinks are on me! ;-) Have a great weekend.

From Dj May 16th, 2008 at 5:56 pm

Hi Dj,

After having a dig around your test file I noticed the #primary_c3 element is positioned absolutely. From what I can see this is you key issue, as IE, when using the AlphaImageLoader, completely messes up the z-indexes of child DOM elements. One option would be to position this elements via floats and margins, removing the need for absolute positioning. Unfortunately there’s nothing programmatically I can of do with the plug-in to help you.

Hope that’s of some help!

From Paul Campbell May 17th, 2008 at 1:00 am

Hi Paul,

This plugin is very valuable to me. Thanks for writing it! I’m experimenting with doing most of the new verison of my site using semitransparent png’s which has proven to be quite an undertaking just for IE6.

The problem I am having, is that if I try to apply the plugin to any div with the sizingMethod: “scale” option set, that div’s width is always extended by about 10px more than the width that was set for that div. Looking through your code, I was not able to locate the reason for this (maybe has something to do with offsetWidth in setDOMElementWidth() ?

Thanks

From Parag Jagdale May 18th, 2008 at 10:16 pm

Hi Paul,

Any suggestions on trying to fix the issue above?
I don’t believe its my CSS, but I’ve tested it and the issue only occurs when I apply the plugin in IE6. Anything you could suggest I look at?

btw… sorry if this post appears in your blog more than once. Apparently this form doesnt like firefox so it never submits. Last time I tried hitting the submit button about 5 times before I switched to IE6 to try again and it worked apparently.

Thanks,
Parag

From Parag Jagdale June 10th, 2008 at 8:39 pm

Hi Paul,
Thanks for this fix. I made a change to the background image regex which I’ve attached a patch for below. It should now only match png backgrounds. The patch also now allows for the repeatMethod “crop”.

Hope its of help.

Cheers,
Greg.
***************
*** 109,134 ****

} else {
var bg = el.css(”backgroundImage”);
! var matches = bg.match(/^url\(”(.*)”\)$/);
! if(matches.length) {
! // Elements with a PNG as a backgroundImage have the
! // filter applied with a sizing method relevant to the
! // background repeat type
! forceWidth(el);
! el.css(”backgroundImage”, “none”);

! // Restrict scaling methods to valid MSDN defintions (or one custom)
! if(el.css(”backgroundRepeat”).indexOf(”repeat”) > -1) {
! var sc = settings.repeatMethod == “repeat” ? “repeat” : “scale”;
! } else {
! var sc = “crop”;
}
- setFilter(el, matches[1], sc);
-
- // IE peek-a-boo for internal links
- el.find(”a”).each(function() {
- $(this).css(”position”, “relative”);
- });
}
}

— 109,139 —-

} else {
var bg = el.css(”backgroundImage”);
!
! if (bg != null) {
! var matches = bg.match(/^url\(”?(.*?\.png)”?\)$/);

! if(matches != null && matches.length) {
! // Elements with a PNG as a backgroundImage have the
! // filter applied with a sizing method relevant to the
! // background repeat type
! forceWidth(el);
! el.css(”backgroundImage”, “none”);
!
! // Restrict scaling methods to valid MSDN defintions (or one custom)
! if(el.css(”backgroundRepeat”).indexOf(”repeat”) > -1) {
! var sc = settings.repeatMethod == “repeat” ? “repeat” : (settings.repeatMethod == “crop” ? “crop” : “scale”);
! } else {
! var sc = “crop”;
! }
!
! setFilter(el, matches[1], sc);
!
! // IE peek-a-boo for internal links
! el.find(”a”).each(function() {
! $(this).css(”position”, “relative”);
! });
}
}
}

From Greg Bryant June 19th, 2008 at 4:19 pm

Hi Paul, love your plugin.

Two issues I am having here: http://www.q2arabia.com/index.php/media_services/mrm

1. The css rollovers don’t seem to be working. The menu is constructed via sprites and i position the background image with a negative background position on hover.
2. On the same page you can see that it somehow broke the float on the image at the top of the page.

Any idea’s on what’s going on here? Any help is greatly appreciated.

From Karim Noseir June 28th, 2008 at 5:05 am

Hello, I was thinking this i a very sweet looking script here… but it dosen’t seem to work in IE6 mind taking a look at the source code of the site… it is the test area. may-be you’ll see something that stands out on why… thanks… :-)

https://www.sjrmc.org/Core/DoctorDirectory/Dir_Hospitalist-Medicine

From jeremyBass July 9th, 2008 at 9:35 pm

N/M :-)

From jeremyBass July 10th, 2008 at 10:32 pm