Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve/hack fading semi-transparent PNG bug in IE8?

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!


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 :)


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.


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.


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');

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