20

Why does this happen? Any workarounds?

jQuery:

$(function() {
   $('p.quote').fadeIn(3000);
});

HTML:

<p>someone said:</p>
<p class="quote">&ldquo;lorem ipsum&rdquo;</p>
<p>someone else said:</p>
<p class="quote" style="display: none;">&ldquo;magna carta&rdquo;</p>
chrisdillon
  • 556
  • 1
  • 6
  • 14

10 Answers10

20

There is a known bug with IE and the fadeIn/fadeOut functions and their effect on text elements. Check out the info here:

http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/

Looks like my original link has since gone dead. Updated with a different solution from the comments:

http://malsup.com/jquery/cycle/cleartype.html

The workaround is to remove the 'filter' property of the element in a callback function after fadeIn() has finished.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • 1
    Well, it's not pretty in that it fades in the aliased text then snaps the filter off, but it works. We need to fade the filter too! Dam IE. – chrisdillon Apr 22 '09 at 17:14
  • 1
    StackOverflow suffers from this very problem (when you click "load new answers"). I hope one of the team sees this answer. – Michael Myers Apr 22 '09 at 17:20
17

I found a better, more general solution, at http://jquery.malsup.com/fadetest.html.

I've taken that and adapted it into a standalone JavaScript file to be included in pages that use the jQuery fade*() methods.

//
//  jQuery IE Fade Fix
//
//  Adapted from code found at http://jquery.malsup.com/fadetest.html.
//
//  This is only needed for IE 7 and earlier, so this is best added to your page using IE's conditional comments
//  (http://msdn.microsoft.com/en-us/library/ms537512%28VS.85%29.aspx) as follows:
//      <!--[if lt IE 8]><script type="text/javascript" src="jquery-ie-fade-fix.js"></script><![endif]-->
//
(function($) {
    $.fn.fadeIn = function(speed, callback) {
        if ($.isFunction(speed) && callback == undefined) {
            callback = speed;
            speed = 'normal';
        }
        return this.animate({opacity: 'show'}, speed, function() {
            if ( $.browser.msie )
            {
                this.style.removeAttribute('filter');
            }
            if ( $.isFunction(callback) )
            {
                callback.call(this);
            }
        });
    };

    $.fn.fadeOut = function(speed, callback) {
        if ($.isFunction(speed) && callback == undefined) {
            callback = speed;
            speed = 'normal';
        }
        return this.animate({opacity: 'hide'}, speed, function() {
            if ( $.browser.msie )
            {
                this.style.removeAttribute('filter');
            }
            if ( $.isFunction(callback) )
            {
                callback.call(this);
            }
        });
    };

    $.fn.fadeTo = function(speed, to, callback) {
        if ($.isFunction(speed) && callback == undefined) {
            callback = speed;
            speed = 'normal';
        }
        return this.animate({opacity: to}, speed, function() {
            if ( to == 1 && $.browser.msie )
            {
                this.style.removeAttribute('filter');
            }
            if ( $.isFunction(callback) )
                {
                callback.call(this);
            }
        });
    };
})(jQuery);

EDIT: Incorporated joeformd's fix for the callbacks.

EDIT2: Added fix for corner case where speed is not defined but callback is -Tomi

Community
  • 1
  • 1
GBegen
  • 6,107
  • 3
  • 31
  • 52
  • That's a great drop-in solution but the callbacks didnt work for me (broke the 'this' scope I think) I've posted a modified version here: http://www.joelanman.com/archives/15 – joeformd Dec 01 '09 at 15:45
  • Thanks @joeformd. I've incorporated your fix into the sample code. – GBegen Dec 03 '09 at 01:07
  • Upvoted this answer. I much prefer this simple drop-in solution. Thanks for sharing. Worked great for me. – Bob Yexley May 20 '10 at 01:18
5

From what I remember, the filter attribute being set causes this. After your fadeIn is complete, remove the filter attribute from the element.

$('p.quote').fadeIn(2000, removeFilter);

function removeFilter() {
  $('p.quote').removeAttr("filter");
}
Brandon Montgomery
  • 6,924
  • 3
  • 48
  • 71
3

Simply apply background color to exact element you fading.. as far as I remember it won't work on children's if if you apply to parent, so it has to be on this very element that gets aliased.

spirytus
  • 10,726
  • 14
  • 61
  • 75
2

Looks like the accepted answer now has a dead link. I think the same information is now available at http://blog.wolffmyren.com/2009/05/28/jquery-fadeinfadeout-ie-cleartype-glitch/.

To preserve the information in StackOverflow, here are the contents of that link:

Thanks to Benjamin Michael Novakovic for this fix!

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');
});

via Benjamin Michael Novakovic » jQuery fadeIn/fadeOut IE cleartype glitch.

GBegen
  • 6,107
  • 3
  • 31
  • 52
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Add this on top of your html documents. It works on IE 8.07xxxx. I'm not sure this technique works on IE 7.

Ezekiel
  • 19
  • 1
1

Add this into your JS. It fixes the bug and maintains the correct scope. When added to jQuery, it still passes all unit tests:

(function($){
    $.each(['fadeIn', 'fadeOut'], function(i, method){
        var _fn = $.fn[method];
        $.fn[method] = function(easing, callbackå, cancel) {
            if ($.isFunction(easing)) {
                callback = easing;
                easing = 'normal';
            }
            return _fn.call(this, easing, function(){
                jQuery.browser.msie && !cancel && this.style.removeAttribute('filter');
                (callback || $.noop).call(this);
            });
        }
    })
})(jQuery);

Written by me :)

Ralph Holzmann
  • 606
  • 7
  • 6
1

This is how I got rid of my ugly faded in text on IE 8: use fadeTo instead and gear it up to 99%!

Therefore this worked for me:

$(function() {
   $('p.quote').fadeTo("slow",0.99);
})
Cosmin
  • 21,216
  • 5
  • 45
  • 60
Tom
  • 11
  • 1
0

None of these solutions worked for me fading in a div using jQuery's animate, as the filter was in the style element. Therefore is what I needed to do:

$(div).animate({opacity: 1}, 800, function() {
   $(this).removeAttr('style');
});

Obviously this will remove any other inline styles you may have too.

Jamie
  • 786
  • 1
  • 7
  • 12
0

None of these solutions worked for me either or else they were unsuitable, for example I don't want to change my HTML5 DTD declaration just for one IE bug, and I can't change my background color as its being used in another animation.

I'm also using jQuery .animate so this may be a little off topic but the solution that worked perfectly was this one. Its a good article but the core code is:

$('#sample').animate(
    {opacity:1.0},
    500,
    function() {
        $(this).css('filter','');
    }
);
edwinbradford
  • 435
  • 5
  • 20