A IE7/8 transparent .png challenge!

A IE7/8 transparent .png challenge! Actually the challenge is this… Find a way to make IE7/8 happy while they animate the opacity of a transparent png image via jQuery.Here is the simple test page. First view in FX and hover over the purple circle - see how nice it is? Now view in IE7 and IE8 and hover over the purple circle - see how horrible that is? That’s happening on my nice home page. The JS links are absolute links, so it’s a ready to go copy and paste test page. Thanks a lot for looking and any ideas you may have. Note: IE does fine with just changing the size on hover. It’s only the Opacity change that makes her go bonkers! And, this is only a png issue, jpg’s and gif’s do not suffer the same fate.

At first glance you may think that this is a JS question, I assure you it is not. This is not a bug with jQuery, but rather a bug in IE7/8 with how they handle pngs. I have been reading and trying things all day and have been unable to come up with a viable solution. The problem/bug goes back a long way, with many discussions, and with little solutions.

My particular fix needs to be able to be applied to an img tag. The img needs to be able to shrink and grow (via the JS block in the head). So, I don’t think any background fixes will work for my situation. Because a background image will not shrink proportionally like an img.

This is for a passionate project of mine, so If anyone could find a solution to this problem, I’d be ecstatic! If you except the challenge and/or want to help, you will find a good start with a search like this… http://www.google.com/search?hl=en&rlz=1B3GGGL_enUS340US340&ei=rQbESt-rOIWAsgOYg4yzCg&sa=X&oi=spell&resnum=0&ct=result&cd=1&q=jquery+FadeIn%28)+png+bug&spell=1

Or here is another supposid solution that I could not make work http://blog.mediaandme.be/?ref=17 Somemore info here http://www.optimalworks.net/blog/2008/web-development/ie-png-filter-problems And here http://jquerytools.org/forum/30/25817 nad even more here http://www.sitepoint.com/forums/showthread.php?t=590295

Personally, I think fading a container around the image (instead of the image itself) is a possible way to fix it. However, that never would fix it when I tried. If all else fails and I can’t fix the source. Then as an alternative, I need to find a way to feed IE NO Opacity in the JS. Then she’s fine and the problem is fixed! However, IE gets less of the cool effect.

Note: a jpg or gif will not work in this instance.

Bump, what do think, any ideas, I’ll try anything? Here is the TEST PAGE again. Thanks!

Hi eric,

The problem is that you can’t use the opacity filter on a png image. I’m guessing that opacity on the png is already being handled by the old filters and you can’t mix the alpha image loader with the opacity filter at the same time (although other filters can be used on the same element).

A quick fix for IE is to set the background colour of the image to the current background (thus losing the opacity) but not having to make any changes to the js.

e.g.


[B]li img{background:#fff;}[/B]


A working example:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Challenge</title>
<meta name="description" content="">
<meta name="keywords" content="" >
<script type="text/javascript" src="http://www.visibilityinherit.com/projects/challenge/js/jquery.js"></script>
<script type="text/javascript" src="http://www.visibilityinherit.com/projects/challenge/js/tabs.js"></script>
<script type="text/javascript">
// #nav Animation 
    $(document).ready(function() {
        // Append shadow image to each LI
        $("#nav li").append('<img class="shadow" src="http://www.visibilityinherit.com/projects/challenge/challenge.png" alt="">');
        // Animate buttons, shrink and fade shadow
        $("#nav li").hover(function() {
            var e = this;
            $(e).find("a").stop().animate({ marginTop: "-14px" }, 250, function() {
                $(e).find("a").animate({ marginTop: "-10px" }, 250);
            });
            $(e).find("img.shadow").stop().animate({ width: "65px", height: "65px", marginLeft: "0", opacity: 0.3 }, 250);
        },function(){
            var e = this;
            $(e).find("a").stop().animate({ marginTop: "4px" }, 250, function() {
                $(e).find("a").animate({ marginTop: "0px" }, 250);
            });
            $(e).find("img.shadow").stop().animate({ width: "117px", height: "117px", marginLeft: "0", opacity: 1 }, 250);
        });                    
    });
</script>
<style type="text/css">
#nav {
    float:left;
    padding:10px
}
li {
    float:left;
    height:117px;
    width:117px;
}
li img {
    background:#fff;
}
</style>
</head>
<body>
<ul id="nav">
    <li><a href="#">challenge</a></li>
</ul>
</body>
</html>


Other than that I can’t see a way of making it work. You can’t add the opacity to another element because the element gets treated as a whole by the filter so it doesn’t matter whetehr its the image or the parent that gets the filter as they are all rendered and then the filter applied.

I tried using a slightly transparent background image instead of the solid color fix but it didn’t seemt ot make a difference.

The fix I offered above makes the thing work but of course only on white backgrounds You would need to change the color depending on the background and of course gradient backgrounds wouldn’t be possible.

Thanks for trying Paul! Yeah, I am very frustrated with this problem. Normally I dont care much, because I think I’ve “lost” to an IE bug maybe twice in my time. But this one I think has me beat, which makes me sad. The background on the img was the first thing I noticed fixed it, but that wont work in my case.

I’ve tried every possible solution on the web I think so far - none fully worked! Applying the opacity to a container around the img sort of worked. As long as you feed the img position relative it kept the bug from appearing, but then of course you also have no opacity (which defeats the purpose). I even tried poping another element with opacity over the top of the shadow on hover. This sort of worked, but didn’t look all that good. I edited the twinHelix png fix to include IE7/8. That sort of worked in IE8 (killed the bug - but still didnt look very good). But this had no effect on IE7.

I finally just had a break through that I think I can live with (as long as no one else can find better). Simply after the script, feed IE opacity: “none”. And all the other animation stuff. I then I can fiddle with the height/width in IE and make it appear smaller, thus giving the illusion in IE that it is gaining transparency.

Check out http://www.bridgeland.com.

Instead of using the PNG as an IMG tag I used a div with a filter in order to make the PNG look clean and not aliased.

I wrapped that filter div with another which I use to apply my opacity fade. On the completion callback of the fade I replace the wrapper div (and PNG div contained) with a normal IMG tag PNG. This one is vanilla and hasn’t had any filters applied to it so it looks completely clean. I use an IE6 PNG fix on this IMG as well so it will load in properly.

Here is the HTML code:


<div id="water">
<!--[if lt IE 7]>
<div class="boat iealphaboat">
<div style="display:block;width:664px;height:340px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src=/images/stories/rotator/boat.png);"></div>
</div>
<img src="/images/stories/rotator/boat.png" class="png-fix ieboat" />
<![endif]-->

<!--[if gt IE 6]>
<div class="boat iealphaboat">
<div style="display:block;width:664px;height:340px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=scale,src=/images/stories/rotator/boat.png);"></div>
</div>
<img src="/images/stories/rotator/boat.png" class="png-fix ieboat" />
<![endif]-->

<![if !IE]>
<img src="/images/stories/rotator/boat.png" class="boat" />
<![endif]>
</div>

Here is the Javascript:


jQuery(function(){
    jQuery('.boat').css('opacity', 0);
    jQuery('.boat').show();
});

jQuery(window).load(function () {
    jQuery('.boat').animate({
        top: '-=210',
        opacity: '1'
    }, 6000, 'easeOutQuint', function() {
        jQuery('.iealphaboat').hide();
        jQuery('.ieboat').show();
    });
});

Here is the CSS:


.boat, .ieboat {position:absolute;width:664px;height:340px;top:256px;left:150px;display:none;}
.ieboat {display:none;top:46px;}
#water{position:relative;height:350px;width:932px;background:black;overflow:hidden;background: url(/images/stories/rotator/water.jpg);}

Hopefully this will help a few people out that run into this problem!

-Matthew
[URL=“http://www.poeticsystems.com”]

Thanks for posting your solution.

I haven’t had time to test it yet but the page looks good. I do notice that in iE6 and IE7 you get a white flash the first time the picture changes but after that it seems to change fine.

Looks like it works perfect. Good job!

I have adjusted the timing of things a little bit to make sure the browser has ample time to do the image replacement so that there is no white flash. Looks good to me now in IE6, IE7, IE8, Firefox and Safari (and mobile safari).