views:

3443

answers:

10

Why does this happen? Any workarounds?

Example: http://chrisdillon.us/jquery_fadein_problem1.html

jQuery:
$(function() {
   $('p.quote').fadeIn(2000);
});

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>
+13  A: 

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
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.
cdillon
StackOverflow suffers from this very problem (when you click "load new answers"). I hope one of the team sees this answer.
Michael Myers
This offers a slight improvement: http://malsup.com/jquery/cycle/cleartype.html
cdillon
downvote for dead link
Ankur Goel
Downvote for a dead link after 6 months...ouch.
Justin Niessner
Upvote to counter stupid downvote.
Pekka
Upvote for undead link - and it solved my problem
CAD bloke
+4  A: 

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
+2  A: 

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  A: 

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) {
     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) {
     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) {
     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.

GBegen
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
Thanks @joeformd. I've incorporated your fix into the sample code.
GBegen
Upvoted this answer. I much prefer this simple drop-in solution. Thanks for sharing. Worked great for me.
Bob Yexley
+1  A: 

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
+1  A: 

I have tried using the jquery.ie.fade.fix.js but it is not working. I added the conditional comment to the HTML and set up the file to point to it in case of IE7 or less but it is not working for me. I am NOT a javascript or jquery coder...just a web designer. Any help would be greatly appreciated.

foxden vixen
+1  A: 

None of this helps fix the same text problem when slideToggle is used instead of fadeIn.

marte
+1  A: 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

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
+1  A: 

Ezekiel, many thanks for your DTD suggestion above. I just discovered this page during a Google search because I was encountering the same problem in IE 8.0.x . Changing my DTD to yours solved the problem. Yet another IE bug - oh joy.

Holly
A: 

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