Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Greg Franklin
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Greg Franklin

Removing Inline Opacity Filters After Fade-In / Fade-Out Transitions In IE8

By Ben Nadel on

Recently, I demonstrated how to use jQuery's .css() method to clear inline CSS left in-place after a jQuery transition. This approach has been working well; but, recently, I found out that this approach falls short in IE8 (and IE7) when dealing with alpha / opacity filters. No matter what I did - no matter which CSS properties I cleared - "filter", "opacity", "-ms-filter" - nothing worked! Thankfully, I came across this GitHub issue posted by Mark Matyas, which demonstrated how to remove the filter property explicitly.


 
 
 

 
  
 
 
 

The trick turned out to be removing the "filter" attribute of the style object after the fade transition had completed:

  • this.style.removeAttribute( "filter" );

I don't know enough about all the inter-browser oddities to really tell you why it happens this way; for years, I've been using jQuery to encapsulate all that detail. And, if you read the source code of jQuery, it looks like it does take this IE-specific oddity into consideration in the CSS-Hooks (see ticket #6652). But, for some reason, my specific context doesn't work.

Anyway, here's a quick demo with this logic in place:

  • <!doctype html>
  • <!--[if lt IE 9]>
  • <html class="lt-ie9">
  • <![endif]-->
  • <!--[if gt IE 8]><!-->
  • <html>
  • <!--<![endif]-->
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Removing Inline Filters After FadeIn / FadeOut In IE
  • </title>
  •  
  • <style type="text/css">
  •  
  • ul li {
  • filter: alpha( opacity = 0 ) ;
  • opacity: 0 ;
  • position: relative ;
  • zoom: 1 ;
  • }
  •  
  • ul.visible li {
  • filter: alpha( opacity = 100 ) ;
  • opacity: 1 ;
  • }
  •  
  • </style>
  • </head>
  • <body>
  •  
  • <h1>
  • Removing Inline Filters After FadeIn / FadeOut In IE
  • </h1>
  •  
  • <ul class="list visible">
  • <li>
  • Thing One
  • </li>
  • <li>
  • Thing Two
  • </li>
  • </ul>
  •  
  • <p>
  • <a href="#" class="toggle">Toggle</a> -
  • <a href="#" class="fader">Fade Out</a>
  • </p>
  •  
  •  
  •  
  • <!-- Load jQuery from the CDN. -->
  • <script
  • type="text/javascript"
  • src="//code.jquery.com/jquery-1.9.1.min.js">
  • </script>
  • <script type="text/javascript">
  •  
  •  
  • // Hook up the toggle to add/remove the visible class.
  • $( "a.toggle" ).click(
  • function( event ) {
  •  
  • $( "ul" ).toggleClass( "visible" );
  •  
  • }
  • );
  •  
  •  
  • // Hook up the fader to fade-out / fade-in the list items.
  • $( "a.fader" ).click(
  • function( event ) {
  •  
  • $( "ul li" )
  • .fadeOut( 1000 )
  • .fadeIn( 1000, handleFade ) // Clean up CSS.
  • ;
  •  
  • }
  • );
  •  
  •  
  • // I handle the clean-up for the fade-in action. This will
  • // execute for EACH item in the transitioning collection.
  • // When this executes, THIS will refere to the DOM element
  • // being faded-in.
  • function handleFade() {
  •  
  • // Clear any inline CSS properties that may be left over
  • // from the fade-in / fade-out transition.
  • $( this ).css({
  • display: "",
  • opacity: "",
  • filter: "",
  • zoom: ""
  • });
  •  
  • // If we are currently working with IE7 / IE8, then
  • // clearing the inline CSS won't actually be enough. We
  • // have to remove the filter attribute explicitly.
  •  
  • var isIE = !! $( "html.lt-ie9" ).length;
  •  
  • if ( isIE ) {
  •  
  • this.style.removeAttribute( "filter" );
  •  
  • }
  •  
  • }
  •  
  •  
  • </script>
  •  
  • </body>
  • </html>

Hope this helps - it took me about 4 hours to get to the bottom of this.




Reader Comments

What is this?

!! $( "html.lt-ie9" ).length

I've never seen that before:
"html.lt-ie9"

Is that a jQuery hook for tesing in IE?

@Roberto,

Hmm, it looks like I'm using 1.9.1 in the video. Maybe there was something else about my setup that was preventing the filter from being removed.

The last 2 lines of JS code was pretty much what I needed to fix the issue I'm having. Thank you for sharing your solution. Cheers!