Monday, February 16, 2009

Font cleartype problems with fadeIn() and fadeOut() in Internet Explorer 7 (IE7)

Have you ever noticed whenever you use jQuery's fadeIn() and fadeOut() functions your text will become edgy. Mozilla and other seem to be rendering fine (not sure about IE6). Anyway, to solve this problem you need to remove the filter attribute from the DOM element that you have faded in/out.

For example:

// This causes this text glich
$("#message").fadeIn();

// This will fix it
document.getElementById("#message").style.removeAttribute("filter");

Screenshots:

SS-20090216194727

SS-20090216194422 

You need to remove the filter attribute after fadeIn() function has completed its job. In other words, as a function callback. Otherwise, fadeIn()/fadeOut() functions would change the opacity of the element, which in turn would cause the filter attribute to be attached yet again. So, remove the attribute in function callback like this:

$('#message').fadeIn(function(){
    this.style.removeAttribute("filter");
});

26 comments:

  1. i would say that this is a bug in jquery.
    may be you can submit a bug report?

    ReplyDelete
  2. This is a known IE bug, so for now, we should deal with it with this workaround...

    ReplyDelete
  3. you can also set a background color on the element in CSS. That fixed it for me a lot of times (though I didn't use jQuery)

    ReplyDelete
  4. Thanks for the tip Michiel, I'll add it to my post...

    ReplyDelete
  5. Great Solution. My banner font size was 40px, and the fade-in on IE6/7 was displaying nasty black border around the text. Setting the background color took care of it. Super! Thanks.

    ReplyDelete
  6. Great tip! Solved my issue. Thanks...

    ReplyDelete
  7. I'm using jQuery InnerFade, which uses the removeFilter workaround. I'm cross-fading both images (PNG ) and text with transparency over text. The black border effect is still visible and the text is not clean. I can't set the background color during the fade or the effect will be worse.

    ReplyDelete
  8. This is not resolving our issue when specifying it as above or using jQuery removeAttr("filter").

    Our situation is a little different, though. We initially do a fadeTo() and then immediately follow with a slideToggle() that contains a callback function. Within the callback function, $ajax is called and its success property calls show(), animate(), and hide().

    Any help is greatly appreciated! Thx!

    ReplyDelete
  9. thanks, excellent hint ....

    ReplyDelete
  10. Background color...who'dathunk it?

    Worked for me

    ReplyDelete
  11. @Jesse, you should apply this fix in .show() callback function in the one that is in your AJAX callback function.

    ReplyDelete
  12. I used the IE fix in the hide() and show() functions and it removed the pixelated effect on texts after the functions were done. However, the ugly effect is still very evident while the animations execute with speed set to slow.

    Many thanks.

    ReplyDelete
  13. Thanks a ton! The background color tip really worked wonders.

    Regards,
    Satish.

    ReplyDelete
  14. Thanks for the post! Solved it for me too!

    ReplyDelete
  15. I experience the described problem with the LoopedSlider (see http://nathansearles.com/loopedslider)

    The fading seems to be done here:

    case 'fade':
    t = [t]*1;
    m = (-(t*w-w));
    current(t);
    if(o.autoHeight){autoHeight(t);}
    jQuery(o.slides,obj).children().fadeOut(o.fadespeed, function(){
    jQuery(o.slides,obj).css({left: m});
    jQuery(o.slides,obj).children(':eq('+(s-1)+')').css({left:s*w-w});
    jQuery(o.slides,obj).children(':eq(0)').css({left:0});
    if(t===s){jQuery(o.slides,obj).children(':eq(0)').css({left:(s*w)});}
    if(t===1){jQuery(o.slides,obj).children(':eq('+(s-1)+')').css({ position:'absolute',left:-w});}
    jQuery(o.slides,obj).children().fadeIn(o.fadespeed);
    u = false;
    });
    break;

    How should I apply the suggested fix here?

    Thanks,
    Walt

    ReplyDelete
  16. @Kirk, try to change it to this:

    t = [t]*1;
    m = (-(t*w-w));
    current(t);
    if(o.autoHeight){autoHeight(t);}
    jQuery(o.slides,obj).children().fadeOut(o.fadespeed, function(){
    jQuery(o.slides,obj).css({left: m});
    jQuery(o.slides,obj).children(':eq('+(s-1)+')').css({left:s*w-w});
    jQuery(o.slides,obj).children(':eq(0)').css({left:0});
    if(t===s){jQuery(o.slides,obj).children(':eq(0)').css({left:(s*w)});}
    if(t===1){jQuery(o.slides,obj).children(':eq('+(s-1)+')').css({ position:'absolute',left:-w});}
    jQuery(o.slides,obj).children().fadeIn(o.fadespeed, function(){this.style.removeAttribute("filter");});
    u = false;
    this.style.removeAttribute("filter");
    });

    ReplyDelete
  17. Thank you very much. That works like a charm!

    Walt

    ReplyDelete
  18. Nice one for this, been banging my head against the wall for hours trying to fix something, and this just did the trick!

    ReplyDelete
  19. Been looking for a workaround for this, thanks for this one. Work's like a dream.

    ReplyDelete
  20. Thanks SO MUCH for this article and BIG BIG thanks @Michiel for the background-color fix! I spent literally the past 4-5 hours reading forums and trying to implement some version of the removeAttribute fix on a quote rotator script, but I could could not get it to work. Then I stumbled upon these comments and the background-color fix blew my mind! I almost didn't try it as it seemed too simple to work! :-D Cannot thank you enough for saving me from what was sure to be a sleepless night!

    ReplyDelete
  21. This works great AFTER the fade transition, but is there any way to fix the font cleartype problem DURING the fade transition in IE?

    ReplyDelete
  22. you are great. liked this lifesaver too much

    ReplyDelete
  23. Hi, just came across this

    Ive a similar problem but with a slider called Feature list.
    In the html document I just have the following, no mention of fade..


    $(document).ready(function() {
    $.featureList(
    $("#tabs li a"),
    $("#output li"), {
    start_item : 0
    }
    );
    });



    Looking at the js file im not sure where to put this, if you can be of any help?

    -----------------------------------

    ;(function($) {
    $.fn.featureList = function(options) {
    var tabs = $(this);
    var output = $(options.output);

    new jQuery.featureList(tabs, output, options);

    return this;
    };

    $.featureList = function(tabs, output, options) {
    function slide(nr) {
    if (typeof nr == "undefined") {
    nr = visible_item + 1;
    nr = nr >= total_items ? 0 : nr;
    }

    tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');

    output.stop(true, true).filter(":visible").fadeOut();
    output.filter(":eq(" + nr + ")").fadeIn(function() {
    visible_item = nr;
    });
    }

    var options = options || {};
    var total_items = tabs.length;
    var visible_item = options.start_item || 0;

    options.pause_on_hover = options.pause_on_hover || true;
    options.transition_interval = options.transition_interval || 10000;

    output.hide().eq( visible_item ).show();
    tabs.eq( visible_item ).addClass('current');

    tabs.click(function() {
    if ($(this).hasClass('current')) {
    return false;
    }

    slide( tabs.index( this) );
    });

    if (options.transition_interval > 0) {
    var timer = setInterval(function () {
    slide();
    }, options.transition_interval);

    if (options.pause_on_hover) {
    tabs.mouseenter(function() {
    clearInterval( timer );

    }).mouseleave(function() {
    clearInterval( timer );
    timer = setInterval(function () {
    slide();
    }, options.transition_interval);
    });
    }
    }
    };
    })(jQuery);

    --------------------------------

    Many thanks in advance Dax

    ReplyDelete