PNG Fix

** Everyone! Please use Drew Diller’s DD_belatedPNG fix over this one. His solution is far more elegant, and frankly, I use his on a commercial basis anyway. I will however, leave this project open for active users **

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)

Read

Comments

Comment by Stephen Moseley on December 31st, 2007 at 3:57 pm

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.

Comment by Stephen Moseley on December 31st, 2007 at 4:35 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

Comment by Paul Campbell on January 2nd, 2008 at 2:40 am

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();
});

Comment by Dave on January 2nd, 2008 at 5:59 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.

Comment by Paul Campbell on January 2nd, 2008 at 8:57 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.

Comment by Stephen Moseley on January 2nd, 2008 at 11:28 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

Comment by Stephen Moseley on January 2nd, 2008 at 11:31 am

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

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

Comment by Stephen Moseley on January 2nd, 2008 at 11:58 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

Comment by Stephen Moseley on January 2nd, 2008 at 12:37 pm

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

Comment by Paul Campbell on January 2nd, 2008 at 1:27 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!

Comment by Dave on January 3rd, 2008 at 5:05 am

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

Comment by Acrobatic on January 4th, 2008 at 4:28 pm

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.

Comment by Paul Campbell on January 5th, 2008 at 5:03 am

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" } );

Comment by Acrobatic on January 5th, 2008 at 8:04 am

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

Comment by kulfi on January 10th, 2008 at 2:12 pm

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 …).

Comment by Paul Campbell on January 10th, 2008 at 2:37 pm

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

Comment by yann on January 12th, 2008 at 6:05 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 :)

Comment by Kit Plummer on January 13th, 2008 at 4:28 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

Comment by Paul Campbell on January 14th, 2008 at 2:07 pm

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

Comment by Andy Frost on January 19th, 2008 at 3:24 am

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.

Comment by Paul on January 22nd, 2008 at 2:26 pm

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

Comment by ryan on February 1st, 2008 at 3:05 am

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

Comment by ryan on February 1st, 2008 at 3:39 am

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

Comment by Woodrow on February 26th, 2008 at 12:23 pm

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

Comment by Woodrow on March 3rd, 2008 at 8:31 am

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.

Comment by Sean O on March 7th, 2008 at 7:02 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…

Comment by amanda on April 14th, 2008 at 4:05 pm

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!

Comment by Ryan on May 6th, 2008 at 11:11 am

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?

Comment by Erik Bruchez on May 12th, 2008 at 4:54 pm

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

-Erik

Comment by Dj on May 15th, 2008 at 4:16 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!

Comment by Paul Campbell on May 16th, 2008 at 1:15 am

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;
}

Comment by Dj on May 16th, 2008 at 5:56 pm

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.

Comment by Paul Campbell on May 17th, 2008 at 1:00 am

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!

Comment by Parag Jagdale on May 18th, 2008 at 10:16 pm

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

Comment by Parag Jagdale on June 10th, 2008 at 8:39 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

Comment by Greg Bryant on June 19th, 2008 at 4:19 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”);
! });
}
}
}

Comment by Karim Noseir on June 28th, 2008 at 5:05 am

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.

Comment by jeremyBass on July 9th, 2008 at 9:35 pm

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

Comment by Alexander on July 13th, 2008 at 4:57 am

Hi!
It’s a very nice plugin, but I have a problem with small icons, that are 16×16 pixels big. With this fix the height becomes 19px, but the width stays at 16px. Is there any way to make the height stay at 16px as it should, without cropping them? I measured it also in your example, and it’s the same there, height is 3 pixels more in IE6 when the fix is applied, then in FF or IE7. In bigger images you don’t see the difference, but in small ones like icons you do. Any idea why or how to fix it?
http://jquery.khurshid.com/ifixpng.php doesn’t have that problem.

Comment by yannick STROOBANTS on July 20th, 2008 at 6:53 am

Hello,
Just a question, in IE6 when i used crop method, i loose the background-position, is there any fix or hack for this problem?

Thanks for your answer!

Comment by inSay on August 6th, 2008 at 12:24 pm

sometimes image loading is too slow and the script sets the image size 28×32 (broken image size). So I moved the core function into img.onload event.

Comment by Dave W on August 6th, 2008 at 8:30 pm

I tried to post this before but I don’t think it worked. First of all, thanks for your effort on this. It’s a very handy tool and super easy to use if you’re already using jQuery, which I usually do. My problem though is that when I use it, AJAX calls that I have attached to mouseover events on anchor tags with embedded PNGs quit working and I don’t know how to fix that. Here’s my code:
http://ravenflight.net/clients/younger-associates/2008.08.01-sh/assets/js/shn.js

As you can see, it’s pretty simple. How can I fix it? Any help would be greatly appreciated. Thanks!
Dave

Comment by John Williams on August 20th, 2008 at 9:46 am

Pretty nice site, wants to see much more on it! :)

Comment by Reinier vG on August 22nd, 2008 at 1:33 am

I’ve started using this plugin just yesterday, and a few things didn’t quite work (right) . First issue was that my PNG backgrounds never got processed. I dived into the code and came up with the following solution:

replace line (97)
var bg = new String(el.css(”backgroundImage”));
to
var bg = new String(el.css(”background-image”));

and replace line (105)
el.css(”backgroundImage”, “none”);
to
el.css(”background-image”, “none”);

another problem was, as mentioned before, that some PNG images are stretched in height when they are less than about 18 pixels in height. I was also able to fix this particular issue

replace lines (79-83)
par.css({
height: el.height(),
width: el.width(),
display: “inline-block”
});
with:
par.css(’height’,el.height()+’px’);
par.css(’width’,el.width()+’px’);
par.css(’display’,'inline-block’);
par.css(’line-height’,'1px’);

Hope this helps :)

Comment by Reinier vG on August 22nd, 2008 at 4:27 am

Addition to my previous post:
After further testing it seems my previous height fix is still flawed. The image is shown correctly, but the container is still a few pixels too high.

And I’ve managed to fix this as well:

After the code in the previous fix…

par.css(’height’,el.height()+’px’);
par.css(’width’,el.width()+’px’);
par.css(’display’,’inline-block’);
par.css(’line-height’,’1px’);

append the following line:

par.css(’font-size’,'1px’);

Comment by Matthew Cieplak on March 2nd, 2009 at 1:09 pm

This works great, except that it makes any pngs that happen to be hidden on page load (e.g., they are only shown on mouseover or click) disappear. This is a dimensions computation problem, so I solved it by just setting them to invisible instead of removing them as you had done:

//el.remove();
el.css({visibility: “hidden”, padding: “0″, margin: “0″});

Comment by Cihat on March 2nd, 2009 at 6:44 pm

Hi good work thanks sohbet

Want to comment?





Submit

Recent comments

  1. bo Couple of things: 1. When using tabs and say adding default value to two t...
  2. Rich I took a similar course at uni, and came across this interesting book... h...
  3. Cihat Hi good work thanks ...
  4. Matthew Cieplak This works great, except that it makes any pngs that happen to be hidden on...
  5. bahman Hello Dear OBAMA I am an iranian, I am very interested to you. I wish y...
Find