title: jQuery: Animate Removal of CSS Property
body: <p>I'm visually "collapsing" some DOM elements using jQuery (by shrinking their width to 0px and fading them out) like this: </p>
  
  <pre><code>$(".slideoutmenu").animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 
  </code></pre>
  
  <p>The width of these elements can vary, but the document is properly laid out through CSS without setting a specific width. </p>
  
  <p>Normally, to re-show these elements I could simply do something like this:</p>
  
  <pre><code>$(".slideoutmenu").stop().show().css({ width: '', opacity: 1 });
  </code></pre>
  
  <p>However, I'd like to animate these elements in reverse (fade in, and expand). </p>
  
  <p>Normally I'd do this with something similar to this: </p>
  
  <pre><code>$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });
  </code></pre>
  
  <p>So this is the obvious attempt:</p>
  
  <pre><code>$(this).children(".slideoutmenu").stop().show().animate({ width: "", opacity: 1 });
  </code></pre>
  
  <p>But this doesn't work.</p>
  
  <p>Ultimately, the problem here is the fixed "250" number in the example above. This doesn't work because the widths are variable. I need to combine the result of using the empty string in the css setter and "animate"... but I can't figure out how to do this. I've tried replacing the "250" with 'undefined', 'null', '-1', '', and I've searched Google... to no avail. </p>
  
  <p>I understand I can probably do some measurement trickery with the element hidden from the user - but I can't imagine this isn't a fairly common issue - so I'm hoping there is a "standard" way to do this, or that it's built in some how and I just don't know about it. </p>
  
  <p>Thanks for reading. </p>
  
  <p>FOLLOW UP: </p>
  
  <p>Based on Michael's kind response, I put together a small quick-and-dirty plugin so I can accomplish this inline. (maybe someone can expand upon the plugin idea and make it better)</p>
  
  <p>Here is the plugin:</p>
  
  <pre><code>(function( $ ){
  
    $.fn.cacheCss = function( prop ) {  
  
      return this.each(function() {
  
        var $this = $(this);
  
  
          if (prop instanceof Array)
          {
              for (var pname in prop)
              {
                  if ($this.data('cssCache-' + prop[pname]) != undefined)
                      continue;
  
                  $this.data('cssCache-' + prop[pname], $this.css(prop[pname]));
              }
          }
          else
          {
              if ($this.data('cssCache-' + prop) != undefined)
                  return $this;
  
              $this.data('cssCache-' + prop, $this.css(prop));
          }
  
          return $this;
  
      });
  
    };
  
  
    $.fn.revertCss = function(settings, prop, animated) {  
  
      if (settings == null)
          settings = {};
  
      return this.each(function() {
  
        var $this = $(this);
  
          if (prop instanceof Array)
          {
              for (var pname in prop)
              {
                  if ($this.data('cssCache-' + prop[pname]) != undefined)
                      settings[prop[pname]] = $this.data('cssCache-' + prop[pname]).replace(/px$/, "");               
              }
          }
          else
          {
              if ($this.data('cssCache-' + prop) != undefined)
                  settings[prop] = $this.data('cssCache-' + prop).replace(/px$/, "");
          }
  
          if (!animated)
            return $this.css(settings);
  
          return $this.animate(settings);
  
      });
  
    };
  
  })( jQuery );
  </code></pre>
  
  <p>And here is how I was able to modify my code to use it:</p>
  
  <p>The origional line which set the css property: </p>
  
  <pre><code>$(".slideoutmenu").animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 
  </code></pre>
  
  <p>was replaced by: </p>
  
  <pre><code>$(".slideoutmenu").cacheCss('width').animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 
  </code></pre>
  
  <p>Now, ".cacheCss('width')" caches the value of the css property before I perform my animation. </p>
  
  <p>And the line I had to "undo" those changes: </p>
  
  <pre><code>$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });
  </code></pre>
  
  <p>was replaced by this:</p>
  
  <pre><code>$(this).children(".slideoutmenu").stop().show().revertCss({ opacity: 1 }, 'width', true);
  </code></pre>
  
  <p>Now, ".revertCss(...)" will use the cached settings to revert my width property (animated!)</p>
  
  <p>I made the plug accept arrays as well, so you could do this too:</p>
  
  <pre><code>.cacheCss(['width', 'height'])
  </code></pre>
  
  <p>and then:</p>
  
  <pre><code>.revertCss(null, ['width', 'height'], true)
  </code></pre>
  
  <p>the third parameter controls whether or not the revert is animated or not.</p>
  
  <p>If you have other properties you want to animate at the same time (like i did with "opacity" in the example earlier) you can pass them in as the first parameter just like you would pass an object into the .animate() function. </p>
  
  <p>I'm sure the plug could be GREATLY improved, but I thought it might be nice to throw it out there anyways.</p>
  
  <p>Also, one more point - I had to replace spurrious "px" at the end of the css values... again, I'm sure there is probably a better way of doing that, but I just used a standard regex. </p>