jQuery fadeIn/fadeOut IE cleartype glitch

While using the jQuery  javascript library today at work, I noticed a glitch under IE7. When fading a html node with the .fadeIn() and .fadeOut() functions in jQuery, IE drops the windows Cleartype rendering; which results in very ugly text. This problem appears to be very common, but no one has a nice solution for the problem.

The most common way to solve this problem is by removing the filter CSS attribute. In normal javascript, it would look like this:

document.getElementById('node').style.removeAttribute('filter');

and in jQuery, it would look like this:

$('#node').fadeOut('slow', function() {
   this.style.removeAttribute('filter');
});

This means that every single time we want to fade an element, we need to remove the filter attribute, which makes our code look messy.

A simple, more elegant solution would be to wrap the .fadeIn() and .fadeOut() functions with a custom function via the plugin interface of jQuery. The code would be exactly the same, but instead of directly calling the fade functions, we call the wrapper. Like so:

$('#node').customFadeOut('slow', function() {
   //no more fiddling with attributes here
});

So, how do you get this working? Just include the following code after you include the jQuery library for the added functionality.

(function($) {
	$.fn.customFadeIn = function(speed, callback) {
		$(this).fadeIn(speed, function() {
			if(jQuery.browser.msie)
				$(this).get(0).style.removeAttribute('filter');
			if(callback != undefined)
				callback();
		});
	};
	$.fn.customFadeOut = function(speed, callback) {
		$(this).fadeOut(speed, function() {
			if(jQuery.browser.msie)
				$(this).get(0).style.removeAttribute('filter');
			if(callback != undefined)
				callback();
		});
	};
})(jQuery);

I have been informed by Steve Reynolds that the US Whitehouse Website is using some of the JS documented on this blog post. I would just like to say thanks to everyone who contributed in the comments. :)

Tags: , , ,

83 comments

  1. This is a pretty neat script. Im going to try and implement this as soon as I have some free time. Thank’s for the in depth information.

    ReplyReply
  2. Hey guys, kind of a noobie when it comes to Jquery, I know this is not the problem that has been addressed but I am having 1 problem in IE7 with Cycle, it is just stacking my images. Works perfect in all other browsers

    http://www.ectomachine.com/portfolio/print

    Any help with this would be beyond appreciated..THANK YOU!!!

    ReplyReply
  3. Thanks for the tips and info.

    ReplyReply
  4. Took a few tries but I think I finally got the hang of it.

    ReplyReply
  5. Hi,

    Is there a demo for this solution?

    Thanks

    ReplyReply
  6. Where do I have to put this code exactly?

    Besides jquery I included the following code into my page:

    http://www.hv-designs.co.uk/tutorials/jquery/js/custom.js

    The last script uses a FadeTo function so where to put your code to have a nicer output?

    Thank you in advance

    ReplyReply
  7. @derdada: you could try this:

    jQuery.fn.fadeTo = function(speed,to,callback) {
        return this.animate({opacity: to}, speed, function() {
            if (to == 1 && jQuery.browser.msie)
                this.style.removeAttribute('filter');
    
            if (jQuery.isFunction(callback))
                callback();
        });
    };
    
    $(document).ready(function(){
    	$(".latest_img").fadeTo("slow", 0.3); // This sets the opacity of the thumbs to fade down to 30% when the page loads
    	$(".latest_img").hover(function(){
    		$(this).fadeTo("slow", 1.0); // This should set the opacity to 100% on hover
    	},function(){
    		$(this).fadeTo("slow", 0.3); // This should set the opacity back to 30% on mouseout
    	});
    
    	$("#text p").fadeTo("slow", 0.3); // This sets the opacity of the thumbs to fade down to 30% when the page loads
    	$("#text p").hover(function(){
    		$(this).fadeTo("slow", 1.0); // This should set the opacity to 100% on hover
    	},function(){
    		$(this).fadeTo("slow", 0.3); // This should set the opacity back to 30% on mouseout
    	});
    
    	$("#div").fadeTo("slow", 0.3); // This sets the opacity of the thumbs to fade down to 30% when the page loads
    	$("#div").hover(function(){
    		$(this).fadeTo("slow", 1.0); // This should set the opacity to 100% on hover
    	},function(){
    		$(this).fadeTo("slow", 0.3); // This should set the opacity back to 30% on mouseout
    	});
    });
    
    ReplyReply
  8. Thank you SO MUCH for this! This has made an average website spectacular! Cheers!

    ReplyReply
  9. Sorry doesn’t work in IE8.

    ReplyReply
  10. This was working great in Firefox but the new IE8 is very buggy. Wish MS would make IE more compliant like the other internet browsers.

    ReplyReply
  11. Like the IE fadeIn/fadeOut fix.

    ReplyReply
  12. Anyone where I can start my own blog.

    ReplyReply
  13. These are nice, thank you. One suggestion is (as per jquery plugin authoring guidelines) to have your customFadeIn and customFadeOut functions return the $(this) input that they were passed in, to allow for method chaining. Thanks!

    ReplyReply
  14. Thanx a lot, saved my live

    ReplyReply
  15. Great tutorial. Have been wondering if this is some sort of bug for a while now :)

    ReplyReply
  16. Isn’t possible to replace this:

    $(el).get(0).style.removeAttribute(‘filter’);

    with this:

    $(el).css(‘filter’,”);

    Or ‘filter’ attribute has to be removed completely?

    ReplyReply
  17. @ReTox: I must admit – I tried this when I first wrote the article and discovered that the attribute needed to be removed. I guess the other way of writing it would be:

    $(el).removeAttr(‘filter’);

    ReplyReply
  18. Thanks for this, gonna work on translating this to mootools for a home project :D

    ReplyReply
  19. Hiya,

    First off great work around for the jquery bug!

    The fix seems to work but wondered if anyone else was having an issue of during the animation where it renders the fadein, that the filter removal applies midway so i get a very brief moment where i can see the text change from non cleartype to cleartype.

    Any insight into this would be very much appreciated as ive been struggling on getting a smooth transition.

    Many thanks in advanced!

    ReplyReply
  20. Thank you – I was going nuts trying to work this one out!

    ReplyReply
  21. I tried this fix in three browsers, Chrome, Firefox and IE. While it works fine in IE, it renders my tags as invisible in Chrome and Firefox.

    ReplyReply

Leave a comment

Additional comments powered by BackType