36

As you know, IE6 has bug that can't display semi-transparent PNG file without using non-standard style like filter. In IE7, this problem is fixed. But It still has some bug about PNG file. It can't correctly display fading semi-transparent PNG file. You can clearly see it when you use show/hide function in jQuery with semi-transparent PNG file. The background of image is displayed with non-transparent black color.

Do you have any idea for solve this question by using jQuery.

Update

Let's see my testing

alt text http://rabu4g.bay.livefilestore.com/y1pGVXLwPdkxudYLmIdnMpWTP_9up-8isxbPKX945Ui4ITnYWnR0msaa2NmUF-qJ-Q4a2AAGaiGHwaFSgR1HeplDIO0bWbyRODI/bug.png

As you see, IE8 always incorrectly displays PNG-24 image. Moreover, IE8 still correctly display PNG-8 image when I fade(jQuery.fadeOut function) it only. But It incorrectly display PNG-8 image when I fade & resize(jQuery.hide function) at the same time.

PS. You can download my testing source code from here.

Thanks,

14 Answers14

20

Hey, I don't know if you're still looking for an answer. A couple of days ago I had the same issue animating a div with a PNG image inside. I tried many solutions and the only one that worked fine is one I coded myself.

The issue seems to be IE lacking opacity support and proper PNG support, so it breaks PNG display after applying an opacity effect (I believe animation frameworks rely on the propietary MSIE filter "AlphaImageLoader" for opacity effect on IE). The curious thing (to me that still don't understand very well) is that this issue can be solved using the same filter to load the image before the animation.

I wrote a simple javascript that applies the filter to every image with .PNG extension. My animations run fine on IE with it.

I copy the code below. I'ts framework independent (it's pure JavaScript), but you have to put it inside your framework's DOM ready event (or use domready.js, like I did).

var i;
for (i in document.images) {
    if (document.images[i].src) {
        var imgSrc = document.images[i].src;
        if (imgSrc.substr(imgSrc.length-4) === '.png' || imgSrc.substr(imgSrc.length-4) === '.PNG') {
            document.images[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='crop',src='" + imgSrc + "')";
        }
    }
}

Please let me know if worked fine for you and if animation runned smooth. Kind regards!

Alejandro García Iglesias
  • 16,222
  • 11
  • 51
  • 64
  • Thanks. But your answer does not totally solve this question. Because old image still exist. Please see my following image. http://i53.tinypic.com/mjvntf.png –  Nov 09 '10 at 04:19
  • 3
    Is there any way to get this fix to work for PNG's that are background image on a animated DOM element? – bgreater Jan 28 '11 at 23:40
  • 3
    @bgreater I wrote [a jQuery plugin that handles background images and `` tags](https://gist.github.com/1318344) based heavily on this answer and [an answer to a similar question](http://stackoverflow.com/questions/1156985/jquery-cycle-ie7-transparent-png-problem/1157006#1157006). – donut Oct 27 '11 at 15:58
  • Alejandro. Thank you so much for your solution above. NOTHING else worked, though I have had the other solutions work in different situations. This bit of JavaScript solved my problem easily and 100% to the desired effect. Thank you very much. – Jamin Dec 07 '11 at 17:33
  • @donut your are awesome! After a whole day looking for a solution that actually works, you have the winner one! – TimPetricola Apr 12 '12 at 20:57
  • Hrmmm, I'd have to both clip (to a specific 10x1 and 1x10 slice and then scale that, all via the AlphaImageLoader. I see that scale is possible via http://blog.creonfx.com/internet-explorer/ie6-png-transparency-css-background-repeat-fix and MSDN says it CAN clip, but provides no documentation on how to do it. I'll have to find out if it can do both and report back! – Allen Rice May 10 '12 at 21:45
  • Yeah it looks like you can only clip OR scale and not both at the same time. I'd have to use separate images instead of the 1 sprite if I want to scale it. – Allen Rice May 10 '12 at 22:41
  • @Allen, you say you can't apply both filters? Why do you need to scale using a IE filter? – Alejandro García Iglesias May 11 '12 at 17:03
  • @Soul_Master I know this question is old, but I don't know why this didn't worked for you, it just applies the filter to the image, doesn't duplicates the image. Maybe there's some other thing you must change in your code? Many people resolved this problem with my answer. Best regards. – Alejandro García Iglesias May 11 '12 at 17:11
  • 2
    It works for most common image element. But I always use background image that your code don't support. –  May 11 '12 at 21:35
  • @GarciaWebDev I'd have to scale the image, because its a repeating background image, and I'd have to clip it, because its an image within a css sprite. AlphaImageLoader can scale OR clip, but not both at the same time. I could always just not use a css sprite but I don't want to do that. – Allen Rice May 11 '12 at 23:56
7

HTML

   <img src="image.png" class="iefix" width="16" height="16" />

in CSS

.iefix
{
 /* IE hack */
  background:none\9; /* Targets IE only */
  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader();
}

easy, fast and nice :)

xsor
  • 1,074
  • 11
  • 11
6

The root cause of the problem appears to be Micrsoft IE's poor support for the PNG alpha-transparency (in any version of IE). IE6 is the worst offender by far, rendering alpha-transparent pixels as a pale blue color. IE7 and IE8 handle PNG alpha-transparency, but can't handle changing the opacity of an alpha-transparent pixel in the PNG – they render as black instead of transparent.

My own fixes for this depend on the situation. Here are some approaches:

  1. Just use a GIF. GIFs won't appear as smooth (because of limited color depth), but the pixels are fully transparent.
  2. Use the IE PNG fix available here: http://git.twinhelix.com/cgit/iepngfix/ -- open up index.html and read the comments.
  3. Animate motion, but don't animate opacity of PNG images.
  4. Conditionally do any or all of the above using either JavaScript tests, conditional comments, or the MSIE-only "behavior" extension to CSS. Here's how any of that might work:

Conditional comments:

<!-- in index.html, in the <head>: -->
<!--[if IE 6]>
<link rel="stylesheet" src="css/ie6only.css" />
<![endif]-->

In the css:

/* ie6only.css */
img { behavior: url("js/iepngfix.htc"); }

Via JavaScript detection:

<script defer type="text/javascript">
if(navigator.appName == "Microsoft Internet Explorer")
{ /* Do IE-specific stuff here */ }
else
{ /* Non-IE-compatible stuff here */ }
</script>

The iepngfix.htc behavior works by replacing the PNG with a blank image (blank.gif) and then using Microsoft's DXImageTransform routines to load the PNG as a filter on the blank image. There are other PNG fixes out there which work by wrapping things in divs or spans, but those will often break your layout, so I avoid them.

Hope this helps.

Zee
  • 204
  • 4
  • 11
5

I've managed a fix to this issue for IE 6/7/8.

Roughly looks like this:

<div class="wrapper">
  <div class="image"></div>
</div>

...

/* I had to explicitly specify the width/height by pixel */
.wrapper
{
  width:100px;
  height:100px;
}

.image
{
  width:100%;
  height:100%;
  background:transparent url('image.png') no-repeat;

  /* IE hack */
  background:none\9; /* Targets IE only */
  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="image.png", sizingMethod="crop");
}

...

$(".wrapper").fadeOut('slow');

Note that the "filter" attribute implicitly targets IE only.

Cmc
  • 193
  • 1
  • 2
  • 7
4

I used this function to preload images into gallery carousel. It's based on Alejandro García Iglesias's answer above. It got rid of the "black halo" in IE 6 & 8.

function preloadImages(id) {
    var c = new Array();
    $(id+' img').each( function(j) {
        c[j] = new Image();
        c[j].src = this.src;

        if ( $.browser.msie ) {
            this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='image',src='"+ this.src +"')"; 
        }
    });

}

Call like this:

preloadImages('#Stage');
Benxamin
  • 4,774
  • 3
  • 31
  • 30
  • 1
    I tried somewhere around a dozen transparency hacks claiming to fix the black halo. This is the only solution I found that worked. Thanks! – joren Aug 08 '12 at 20:53
4

I just found the way to solve problem by chance when I try to fix IE8 bug in the following image.

enter image description here

The easiest way, You just define background of current image like the below code. Or you can see full source code and demo on my JsFiddle

#img2
{
    background:#fff;   
}

However, if you have some complex image like my bug, you should try to add almost invisible layer below your image and set background color to some color that you like.

enter image description here

user229044
  • 232,980
  • 40
  • 330
  • 338
  • 6
    sadly, if you want to have some other image behind your front image this won't work - you may as well use a non-transparent image, with the background colour you want. Clearly your solution is simpler when you're using an image on many different colour backgrounds, but it doesn't really solve the problem. – Peter Bagnall Oct 21 '11 at 11:09
2

Why don't you try with PNG8. PNG8 is widely known as full transparent as is GIF file format. However exported with Fireworks it can be semi-transparent as is PNG24. The advantage is that IE6 displays the PNG8 with semi-transparent pixels as it is a GIF - or with full transparency, but IE7 and 8 display it correctly as PNG24 and if you fade it with jQuery or whatever js library it will no display the background with gray, because it does not use the famous -filter property.

sth
  • 222,467
  • 53
  • 283
  • 367
stoimen
  • 562
  • 3
  • 7
  • I can't use Png-8 instead of Png-24. It hasn't any benefit for semi-transparent image. Moreover, I can't create semi-transparent Png-8 by using Photoshop CS4. –  Jul 30 '09 at 06:44
  • Well as it appears you can generate semi-transparent PNG8 without the help of Fireworks. Check for the pngquant. – stoimen Jul 30 '09 at 07:44
  • PNG8s are good for some things but they don't help the IE6 transparency issue much. Transparent PNG8s still look terrible in IE6, just in a slightly different way. – Danyal Aytekin Mar 11 '11 at 14:19
2

i use a modified PNG fix for IE6 it works just great:

(function ($) {
if (!$) return;
$.fn.extend({
    fixPNG: function(sizingMethod, forceBG) {
            if (!($.browser.msie)) return this;
            var emptyimg = "x.gif"; //Path to empty 1x1px GIF goes here
            sizingMethod = sizingMethod || "scale"; //sizingMethod, defaults to scale (matches image dimensions)
            this.each(function() {
                    var isImg = (forceBG) ? false : jQuery.nodeName(this, "img"),
                            imgname = (isImg) ? this.src : this.currentStyle.backgroundImage,
                            src = (isImg) ? imgname : imgname.substring(5,imgname.length-2);
                    this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + sizingMethod + "')";
                    if (isImg) this.src = emptyimg;
                    else this.style.backgroundImage = "url(" + emptyimg + ")";
            });
            return this;
    }
});
})(jQuery);

dont forget to upload x.gif. (a transparent 1x1 gif)

meo
  • 30,872
  • 17
  • 87
  • 123
  • Looks like this came from http://stackoverflow.com/questions/1156985/jquery-cycle-ie7-transparent-png-problem/1157006#1157006 – donut Oct 26 '11 at 21:24
1

Nothing really worked for me so far that I've read combining both opacity settings through CSS, and transparent PNGs. This solution ended up working for me on an animated opacity page on IE8. Other solutions listed on this page didn't work.

#img {
    background:transparent;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50) progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png')"; /* IE8 */
    zoom:1;
    width:600px;
    height:400px;
}

<div id='img'></div>

Note the filter has an Alpha filter first, then the AlphaImageLoader.

Greg Tatum
  • 1,122
  • 10
  • 12
1

The advantage is that IE6 displays the PNG8 with semi-transparent pixels as it is a GIF - or with full transparency, but IE7 and 8 display it correctly as PNG24 and if you fade it with jQuery or whatever js library it will no display the background with gray, because it does not use the famous -filter property.

There is only one way in IE to do an opacity transform. filter: alpha(opacity:). How else should jQuery do this?

Erik
  • 11
  • 1
0

Use Unit PNG Fix for semitransparent png-24.

VVS
  • 2,147
  • 1
  • 13
  • 13
0

Im having the same annoying problem with IE8 and IE7.. anyone tested if Cmc solutions does the trick?

My url is http://www.onlinebrand.dk (Top menu fades in, like Google :) But IE don't care.)

EDIT: Just tested it myself, and even if I set width and height of, well the repeating img. It doesn't work

I just found another work around, where Fadein a wrapper instead of the div with the .png bg image. And it sort of worked, Im now getting som sort of transparency in IE, but also, some padding/margin..Totally wierd..

Bill Gates, Whats up with this? Why can't we get along?

0

This can be done similar to what Stu has done here: http://www.cssplay.co.uk/menus/flyout_horizontal.html

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • I only have problem when I try to fade semi-transparent image(png). Your example is just simple displaying semi-transparent image not fading it. –  Jun 11 '10 at 07:22
0
  1. Define a solid background color to your image:

    .container img { background-color: white; }

  2. Define the background-image css property of your image to its src attribute:

    $('img.png-trans').each(function() { $(this).css('background-image', $(this).attr('src')); });

Advantage: you don't need to change your markup

Disadvantage: sometimes applying a solid background color is not an acceptable solution. It normally is for me.

ThiagoAlves
  • 1,313
  • 16
  • 25