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. :)
Awesome.
I have struggled with this side effect for a while. I did some research but was unable to find a solution.
You are right – it sure does look ugly when you have ClearType applied to everything except the animation areas – especially when the animation usually draws attention to it.
Nice fix, I am definitely going to put this to use.
Great to find this code, in my case it works only the first time. The second time I fade an element it does not work anymore.
Thanks,
Peter
@Bryan Great! Let me know if you have any issues.
@Peter Interesting behaviour, are you using IE6 or IE7? I’ll have a play with this tomorrow on my work computer and see if I can replicate your bug. Thanks for letting me know. :)
@Peter
I just tested under IE6 and the behaviour is fine. Can you give me a few more details on your setup?
Thanks man, but I tested this and it didn’t seem to work under niether IE6 nor IE7
@hasen
Strange. This script only solves the cleartype bug after the fades have actually occurred. I’m not even sure it is possible to fix the text during the fade.
I’ll have another try today, but I’m pretty sure it works fine.
We are all talking about cleartype here, not anti-aliasing?
It definitely is the Cleartype – I’ve just turned both Cleartype and Javascript off in IE7; it looks the same as when BOTH are on (horrible!)
Sadly, your function didn’t work for me either. I’m using jQuery 1.2.3.
My fonts don’t look too bad in IE6, btw ??!)
Think I’m going to try & use the Cycle plugin for absolutely everything! http://malsup.com/jquery/cycle/cleartype.html
I haven’t investigated the uncerlying code …
Hmm – interesting. I have seen that Cycle plugin. I might look into the code to see how they solve the problem. Interesting that the code above works perfectly for me in IE6 and IE7.
I don’t understand, either. It should have worked; did load & run as far as I can tell …
[...] Benjamin Michael Novakovic » 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. (tags: javascript jquery cleartype) [...]
How would I implement your fix with this code? I’m having the same issues with IE6 and IE7. Thank you for posting this!
Here is my code:
function runIt() { $('.bracket span').fadeIn(900).fadeOut(900).fadeIn(900).fadeOut(900, runIt); } runIt(); $('.box').hide(); $('a.show').hover( function() { $('.box').show('slow').animate({opacity: "0.9"}, {duration: 500, complete: stopblinking}); }, function () { $('.box').hide(1000, runIt); } ); function stopblinking() { $('.bracket span').stop('runIt').fadeTo(300, 1.0); }function runIt() { $('.bracket span').fadeIn(900).fadeOut(900).fadeIn(900).fadeOut(900, runIt); } runIt(); $('.box').hide(); $('a.show').hover( function() { $('.box').show('slow').animate({opacity: "0.9"}, {duration: 500, complete: stopblinking}); }, function () { $('.box').hide(1000, runIt); } ); function stopblinking() { $('.bracket span').stop('runIt').fadeTo(300, 1.0); }Here’s an improvement on the original code. Includes a fadeTo function as well.
//------------------------------------------------------------------------------------------------------- // ClearTypeFadeTo / ClearTypeFadeIn / ClearTypeFadeOut // // Custom fade in and fade out functions for jQuery that will work around // IE's bug with bold text in elements that have opacity filters set when // also using Window's ClearType text rendering. // // New Parameter: // bgColor The color to set the background if none specified in the CSS (default is '#fff') // // Examples: // $('div').ClearTypeFadeIn({ speed: 1500 }); // $('div').ClearTypeFadeIn({ speed: 1500, bgColor: '#ff6666', callback: myCallback }); // $('div').ClearTypeFadeOut({ speed: 1500, callback: function() { alert('Fade Out complete') } }); // // Notes on the interaction of ClearType with DXTransforms in IE7 // http://blogs.msdn.com/ie/archive/2006/08/31/730887.aspx (function($) { $.fn.ClearTypeFadeTo = function(options) { if (options) $(this) .show() .each(function() { if (jQuery.browser.msie) { // Save the original background color $(this).attr('oBgColor', $(this).css('background-color')); // Set the bgColor so that bold text renders correctly (bug with IE/ClearType/bold text) $(this).css({ 'background-color': (options.bgColor ? options.bgColor : '#fff') }) } }) .fadeTo(options.speed, options.opacity, function() { if (jQuery.browser.msie) { // ClearType can only be turned back on if this is a full fade in or // fade out. Partial opacity will still have the problem because the // filter style must remain. So, in the latter case, we will leave the // background color and 'filter' style in place. if (options.opacity == 0 || options.opacity == 1) { // Reset the background color if we saved it previously $(this).css({ 'background-color': $(this).attr('oBgColor') }).removeAttr('oBgColor'); // Remove the 'filter' style to restore ClearType functionality. $(this).get(0).style.removeAttribute('filter'); } } if (options.callback != undefined) options.callback(); }); }; $.fn.ClearTypeFadeIn = function(options) { if (options) $(this) .css({ opacity: 0 }) .ClearTypeFadeTo({ speed: options.speed, opacity: 1, callback: options.callback }); }; $.fn.ClearTypeFadeOut = function(options) { if (options) $(this) .css({ opacity: 1 }) .ClearTypeFadeTo({ speed: options.speed, opacity: 0, callback: options.callback }); }; })(jQuery);Thanks cherryaa. That Cycle plugin looks great.
Great! Thanks for the Neil. I was actually working on somthing similar at the moment, but it appears you beat me to it!
From what I gather, you only need to save the background colour for IE6, and in IE7 simply removing the filter attribute should fix the problem.
The Cycle Plugin author has released similar versions to mine: http://malsup.com/jquery/fadetest.html
It appears his work, but mine don’t. Can anyone else test that link to see if the fade works on in IE7? I realise it probably won’t work in 6 as it doesn’t do any background hacking.
Cheers
@neil – The cleartype fading in your link works in IE7.
Err I meant @ben…
Any idea how to fix this same problem with the .show() effect??
Well you could do it the same way I guess.
Just define a new show method; for example customShow().
(function($) { $.fn.customShow = function(speed, callback) { $(this).fadeIn(speed, function() { if(jQuery.browser.msie) $(this).get(0).style.removeAttribute('filter'); if(callback != undefined) callback(); }); }; })(jQuery);I tried replacing
.show(slow)
with
.show(‘slow’,function(){this.style.removeAttribute(‘filter’);})
and then firebug in firefox goes nuts
showing thousands of errors saying “this.style.removeAttribute is not a function”
Any ideas?
well you will need to test if its IE as firefox has no idea what removeAttribute is.
try something like this:
.show(’slow’,function(){ if(jQuery.browser.msie) this.style.removeAttribute(’filter’);})
I still can’t get it to work for the show function. If anyone can figure it out I’m sure there are many people who will need the .show(slow) effect to show clearly in ie also.
@nitwit
Did you try to plugin I posted a few comments above?
to use it, you need to call .customShow() rather than just .show()
Or, you try this extra function
jQuery.fn.customShow = function(speed, callback) { if(typeof speed != 'undefined') { return this.animate({opacity: 'show'}, speed, function() { if (jQuery.browser.msie) this.style.removeAttribute('filter'); if (typeof callback == 'function') callback(); }); } else { this.show(speed, callback); } };Thanks that last example made sense to my dumass so it is working. Many thanks.
One other small thing to note though is that your fix (which will work great for me) still doesn’t replicate that growing effect that the original .show() does. -probably not worth your time though man, and thanks again because the fade-in effect with the clear-type fix will work great for me
Nice. Works, only thing is during transition it still aliases, other than that it’s perfect.
Thanks!
Cheers mate, it looks much better now ;)
if you have a fadein-fadeout image on a text this css style will help you to render the page healthy on ie7.
#txt{
filter:alpha(opacity=100);
}
example : http://demo.trafo.com.tr/atasay/#/products
Have you tried adding just a css property – background-color to the element you are trying to animate. Fixed my issue.
The callbacks in these examples never seem to work for me; so if I have something like this:
[code]thumb.customFadeTo('fast',1).addClass('selected');[/code]
The ‘selected’ class is never added to the object, and I receive a JS error that “thumb.customFadeTo(“fast”, 1) is undefined”.
Any ideas?
@Dmitri:
that worked for me dmitri, thanks!
[...] doing a small bit of searching, I discovered the solution over on Benjamin Novakovic’s blog. In his example he uses fadeIn, and fadeOut, but these functions both have a similar footprint to [...]
Great! Thank you so much for this solution :)
Here’s my java code. It’s an accordian, and I would like to fix the problem. If anyone can make a suggestion they know will work I’d be grateful. Thanks!
var slider=function(){ var array=[]; var speed=10; var timer=10; return{ init:function(t,c){ var s,ds,l,i,y; s=document.getElementById(t); ds=s.getElementsByTagName('div'); l=ds.length; i=y=0; for(i=0;i<l;i++){ var d,did; d=ds[i]; did=d.id; if(did.indexOf("header")!=-1){ y++; d.onclick=new Function("slider.process(this)"); } else if(did.indexOf("content")!=-1){ array.push(did.replace('-content','')); d.maxh=d.offsetHeight; if(c!=y){ d.style.height='0px'; d.style.display='none' } else{ d.style.display='block' } } } }, process:function(d){ var cl,i; cl=array.length; i=0; for(i;i<cl;i++){ var s,h,c,cd; s=array[i]; h=document.getElementById(s+'-header'); c=s+'-content'; cd=document.getElementById(c); clearInterval(cd.timer); if(h==d&&cd.style.display=='none'){ cd.style.display='block'; this.islide(c,1); } else if(cd.style.display=='block'){ this.islide(c,-1)} } }, islide:function(i,d){ var c,m; c=document.getElementById(i); m=c.maxh; c.direction=d; c.timer=setInterval("slider.slide('"+i +"')",timer) }, slide:function(i){ var c,m,h,dist; c=document.getElementById(i); m=c.maxh; h=c.offsetHeight; dist=(c.direction==1)?Math.round((m-h)/speed):Math.round(h/speed); if(dist<=1){ dist=1 } c.style.height=h+(dist*c.direction)+'px'; c.style.opacity=h/c.maxh; c.style.filter='alpha(opacity='+(h*100/c.maxh)+')'; if(h(m-2)&&c.direction==1){clearInterval(c.timer) } } }; } ();Sorry, missed that little format tag.
var slider=function(){ var array=[]; var speed=10; var timer=10; return{ init:function(t,c){ var s,ds,l,i,y; s=document.getElementById(t); ds=s.getElementsByTagName('div'); l=ds.length; i=y=0; for(i=0;i<l;i++){ var d,did; d=ds[i]; did=d.id; if(did.indexOf("header")!=-1){ y++; d.onclick=new Function("slider.process(this)"); } else if(did.indexOf("content")!=-1){ array.push(did.replace('-content','')); d.maxh=d.offsetHeight; if(c!=y){ d.style.height='0px'; d.style.display='none' } else{ d.style.display='block' } } } }, process:function(d){ var cl,i; cl=array.length; i=0; for(i;i<cl;i++){ var s,h,c,cd; s=array[i]; h=document.getElementById(s+'-header'); c=s+'-content'; cd=document.getElementById(c); clearInterval(cd.timer); if(h==d&&cd.style.display=='none'){ cd.style.display='block'; this.islide(c,1); } else if(cd.style.display=='block'){ this.islide(c,-1)} } }, islide:function(i,d){ var c,m; c=document.getElementById(i); m=c.maxh; c.direction=d; c.timer=setInterval("slider.slide('"+i +"')",timer) }, slide:function(i){ var c,m,h,dist; c=document.getElementById(i); m=c.maxh; h=c.offsetHeight; dist=(c.direction==1)?Math.round((m-h)/speed):Math.round(h/speed); if(dist<=1){ dist=1 } c.style.height=h+(dist*c.direction)+'px'; c.style.opacity=h/c.maxh; c.style.filter='alpha(opacity='+(h*100/c.maxh)+')'; if(h(m-2)&&c.direction==1){clearInterval(c.timer) } } }; } ();Thanks a lot, it worked for me pretty fine
There is a way to solve this for many scenarios in IE7.
If, for example, you want to fade in a DIV containing text, you can avoid the ClearType issue by using an opaque overlay of the background color and fading it out. As a result, your DIV will “appear” to be fading smoothly, with no loss of ClearType.
This works very well, but it’s annoying to have to use it, and, of course, it really only works when you can determine the size and background color of the DIV so that you can correctly size and color the overlay.
@blugrasmaniac: Interesting that you do it that way. Funnily enough, I prefer to do it that way too, and with a little extra JS you can stretch the load screen to the correct size of the parent, that way you get a perfect transition.
This method is also better than fading the actual content because if you are fading tables with % widths in firefox, the columns will jump and change width. Using the overlay div solves this problem.
If you use the toggle function with a speed parameter, the ClearType problem occurs in IE 6 & 7 and this seems to fix it there too, as far as I can tell.
(function($) {
$.fn.customToggle = function(speed, callback) {
$(this).toggle(speed, function() {
if(jQuery.browser.msie)
$(this).get(0).style.removeAttribute(‘filter’);
if(callback != undefined)
callback();
});
};
})(jQuery);
Thanks a lot for this idea. It worked fine. Getting rid of ugly IE text, wonderful.
@Neil Monroe:
Am I doing something wrong? I can’t get your function to take the background color parameter, it’s always white no matter what I pass:
$(“#mood”).ClearTypeFadeIn(“slow”, “#2b2b2b”);
@blugrasmaniac and @ben
Could you explain more detailled how this works? I’ve bee fighting with this same problem for a long time and nothing seems to be working :(
[...] Um programador jQuery Benjamin Michael Novakovic criou uma função que pode ser usada para resolver o problema e o com as funções fadeIn() e [...]
The following code will cause cleartype rendering to be restored at the end of an animation for IE7. Note that IE6 simply needs an explicit background colour to be set on the fading element for cleartype rendering to be preserved throughout the animation.
jQuery.fn.fadeIn = function(speed, callback) {
return this.animate({opacity: ‘show’}, speed, function() {
if (jQuery.browser.msie)
this.style.removeAttribute(‘filter’);
if (jQuery.isFunction(callback))
callback();
});
};
jQuery.fn.fadeOut = function(speed, callback) {
return this.animate({opacity: ‘hide’}, speed, function() {
if (jQuery.browser.msie)
this.style.removeAttribute(‘filter’);
if (jQuery.isFunction(callback))
callback();
});
};
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();
});
};
[...] a number of possible solutions exist; detailed by Matt Berseth (link above) and Benjamin Novakovich. If this problem is driving you up the wall like it has me, regrettably there’s no actual [...]
@gxlrygt:
Simply adding a background-color: #fff; (e.g.) to the problem element(s) worked for me too. Thanks for that.
Chris
Just a note: you should update the example in the OP to use $.support.opacity instead of $.browser.msie to keep things compatible with newer versions of jQuery.
thanks man for your great code!
Kudos! I have been battling the clear type issue with IE7. There is a still a shift when the fading is in progress but at the end the text looks good.
Thanks, again.
Kudos! I have been struggling with the clear type issue in IE7 and this code fixed it. Should note that there is still a shift while the animation (fading) is taking place, but at the end, the text looks good.
Thanks again.
A Workaround to prevent the fuzzy text effect with FadeOut/FadeIn on “IE 7″ is to use the jQuery functions: slideUp/slideDown/slideToggle instead of fadeOut/fadeIn/hide/show
sebastian
regards
Thank you! This works great!
Thanks for the tip! Great IE tweak.
instead of ‘this.style.removeAttribute(‘filter’);’
I did use this though. Worked great.
‘$(this).css(“filter”, “”);’
Thanks again mate.
Works great! Thank you very much.
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.
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!!!
Thanks for the tips and info.
[...] jQuery fadeIn/fadeOut IE cleartype glitch [...]
Took a few tries but I think I finally got the hang of it.
Hi,
Is there a demo for this solution?
Thanks
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
@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 }); });Thank you SO MUCH for this! This has made an average website spectacular! Cheers!
Sorry doesn’t work in IE8.
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.
Like the IE fadeIn/fadeOut fix.
Anyone where I can start my own blog.
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!
Thanx a lot, saved my live
Great tutorial. Have been wondering if this is some sort of bug for a while now :)
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?
@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’);
Thanks for this, gonna work on translating this to mootools for a home project :D
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!
Thank you – I was going nuts trying to work this one out!
[...] pueda interpretar el fading que estamos añadiendo. Esta maravillosa función es una ocurrencia de Benjamin Michael Novakovic. Cuando se hace hover la visibilidad del bloque se degrada desde 0 a 100 para lograr un lindo [...]
[...] Read Michaels full article on solving the issue here: http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/ [...]
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.
[...] jQuery fadeIn/fadeOut IE Cleartype Glitch [...]
[...] wasn’t really acceptable.I found a bunch of posts about the issue, Ben Novakovic’s “jQuery fadeIn/fadeOut IE cleartype glitch” looked to get a lot of coverage. This may help for some, but I couldn’t get it going for my [...]
[...] $('.pr_teaser').show(); $('.moreteaser, .lessteaser').toggle(); }); Or you should be able to remove the filter from IE if you are good with jquery (I'm not) and is a question for the js forum. [...]
[...] 本文翻译自:http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/ [...]
[...] It mat be the cleartype glitch mentioned here when using jquery fades. __________________ http://www.pmob.co.uk CSS FAQ 3 col demo Read My CSS [...]
[...] http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/ [...]