jQuery fadein / fadeout of transparent png in IE7 and Chrome


#1

Hi,

I've been looking for any solution to a problem I am having, but have of yet found no such solution. I am using the jquery fadein and fadeout on a transparent png. In firefox, this works great. However, in IE7, during the fade, the transparent area is black. In Chrome, this area is white.

This may have something to do with the way these browsers handle opacity on transparent png's? I'm just not sure, and I didn't find much help on the net.

Any suggestions / solutions would be much appreciated. Thanks!

Jason


#2

It looks like someone succeeded by putting the png inside a container and fading that container instead.
jQuery Development - IE7 .png transparency bug on fadeIn and fadeOut

It's a known issue though and no doubt one that the jQuery development team aren't pleased about.


#3

Thanks pmw57...

I attempted to wrap the element both in a div and span tag, but neither method seemed to work for me. Perhaps I'm implementing the strategy wrong? Below is the code that I'm using.

HTML:

<span id="logoRoll">
	<a href="index.php">
		<img src="assets/images/logoRollover.png" alt="Osteopathic Physicians" />
	</a>
</span>

CSS:

span#logoRoll { position: absolute; left: 250px; top: 23px; width: 73px; height: 21px; display: none; z-index: 1000; }

JS:

$(function(){
	$("img#logo").hover(function(){
			$("span#logoRoll").fadeIn(250);
		},function (){
			$("span#logoRoll").fadeOut(300);
		}
	);
});

Using this method, there is still a black border in IE and a white border in Chrome during the fade.

The only solution may be graceful degradation?


#4

Has anyone successfully achieved this by wrapping a transparent png within a div and faded the div in? It certainly didn't work for me using the above method.


#5

The solution I came up with is not ideal, so first let me start by asking anyone who comes up with a solution and runs across this thread, to please post.

I first checked to see what kind of degradation I would get using transparent gif's. While this worked to an extent, the quality and transparency was not acceptable, so I moved on.

I resorted to only performing the fadeIn and fadeOut function when the user was browsing from Firefox or Safari. These browsers are able to perform a fadeIn and fadeOut on a transparent png.

I first marked the problem images with a specific class. Then, Using Peter-Paul Koch's JavaScript browser detection object (found here), I only allow the fade to occur if the user's browser is Firefox or Safari. Otherwise, these specific images will not fade, the image will simply switch to the transparent image on rollover.

For this to work in IE 6, you need to make sure to use one of the transparent png fixes on the image. I use an edited version of Unit Interactive's PNG fix (found here). My edit takes out the background fix code and targets only specified images.

While I'm still searching for a true fix to this issue, this will suffice for now. It minimally effects this website and still keeps the nice transparent images.

Best,
Jason


#6

Hi,

I kind of made up a solution, by changing opacity values for IE and disabling opacity change for Chrome.

Here you go:

//jQuery.browser alteration for Google Chrome detection
//source: javascriptly.com/2008/09/javascript-to-detect-google-chrome/
var userAgent = navigator.userAgent.toLowerCase();
jQuery.browser = {
  version: (userAgent.match( /.+(?:rv|it|ra|ie|me)[\\/: ]([\\d.]+)/ ) || [])[1],
    chrome: /chrome/.test( userAgent ),
    safari: /webkit/.test( userAgent ) && !/chrome/.test( userAgent ),
    opera: /opera/.test( userAgent ),
    msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
    mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

rolloverFade = {
  init: function() {
    if (jQuery.browser.chrome) { 
      this.preloadWithoutFade(); //rollover without fade for chrome
    }
    else {
      if (jQuery.browser.msie) { //IE
        minOpacity = "0.4"; maxOpacity = "0.6"; 
      }
      else { //other browsers
        minOpacity = "0.8"; maxOpacity = "1.0"; 
      }
      this.preloadWithFade();
    }
        
    function rolloverMouseOver () { $(this).attr( 'src', rolloverFade.newimage($(this).attr('src'))); if (!jQuery.browser.chrome) { $(this).fadeTo("slow", maxOpacity)}};
    function rolloverMouseOut  () { $(this).attr( 'src', rolloverFade.oldimage($(this).attr('src'))); if (!jQuery.browser.chrome) { $(this).fadeTo("slow", minOpacity)}};

    //hoverIntent config start
    var config = {    
     sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)    
     interval: 50, // number = milliseconds for onMouseOver polling interval    
     over: rolloverMouseOver, // function = onMouseOver callback (REQUIRED)    
     timeout: 0, // number = milliseconds delay before onMouseOut    
     out: rolloverMouseOut // function = onMouseOut callback (REQUIRED)    
    };
    //hoverIntent config end

    $(".rolloverFade").hoverIntent(config);
  },
  preloadWithFade: function() {
    $(window).bind('load', function() {
      $('.rolloverFade').each( function( key, elm ) { $('<img>').attr( 'src', rolloverFade.newimage( $(this).attr('src') ) ); });
      $(".rolloverFade").fadeTo("fast", minOpacity); 
    });
  },
  preloadWithoutFade: function() {
  $(window).bind('load', function() {
    $('.rolloverFade').each( function( key, elm ) { $('<img>').attr( 'src', rolloverFade.newimage( $(this).attr('src') ) ); });
    });
  },
  newimage: function( src ) { 
    return src.substring( 0, src.search(/(\\.[a-z]+)$/) ) + '_hover' + src.match(/(\\.[a-z]+)$/)[0]; 
  },
  oldimage: function( src ) { 
    return src.replace(/_hover\\./, '.'); 
  }
};
//--> 

<!--
$(document).ready( function() {
  rolloverFade.init();
});
//-->

If you don't want to use hoverIntent, just delete everything between "hoverIntent config start" and "hoverIntent config end" and change

$(".rolloverFade").hoverIntent(config);

with

$(".rolloverFade").hover(config);

Hope it works.

Cheers,
Stefan


#7

Almost gave up on the black borders/shadow on PNGs in IE7 and IE8 but finally solved this using Unit's PNG fix. Try it.. works a charm on Jquery cycle and other animated effects.

(I'd post the URL but I'm newly registered and can't)


#8

The unitpng fix does work to fix both images with transparent png's as well as transparent png's used as element background images. It doesn't work well with a css-sprite implementation though as it alters background positioning.


#9

FIXED!

I've been wrestling with the same issue, and just had a breakthrough! We've established that if you give the image a background color or image, the png displays properly on top of it. The black border is gone, but now you've got an opaque background, and that pretty much defeats the purpose.

Then I remembered a rgba to ie filter converter I came across. (Thanks be to Michael Bester). So I wondered what would happen if I gave my problem pngs an ie filtered background emulating rgba(255,255,255,0), fully expecting it not to work, but lets try it anyway...

.item img {
	background: transparent;
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)"; /* IE8 */   
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);   /* IE6 & 7 */      
	zoom: 1;

}

Presto! Goodbye black, and hello working alpha channels in ie7 and 8. Fade your pngs in and out, or animate them across the screen - it's all good.


#10

dan.tello thak you! Old post I know but this is just great. I have been wrestling with the transparecy issue for days

Paul MacLean
<snip/>


#11

dan.tello,

Thank you, thank you, thank you for the solution! I've been struggling with this for over a week and was about to give up, until I stumbled across your post. Good sleuthing!

-Steve


#12

Thank you dan.tello,

You saved my day !