Animate Height/Width to “Auto”
It's not possible to do thing.animate({ "height": "auto" });. So this is Darcy Clarke's method to allow that to work. You essentially clone the element, remove the fixed heights currently inflicting the element, and measure/save the value. Then you animate the real element to that value.
jQuery.fn.animateAuto = function(prop, speed, callback){
var elem, height, width;
return this.each(function(i, el){
el = jQuery(el), elem = el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
height = elem.css("height"),
width = elem.css("width"),
elem.remove();
if(prop === "height")
el.animate({"height":height}, speed, callback);
else if(prop === "width")
el.animate({"width":width}, speed, callback);
else if(prop === "both")
el.animate({"width":width,"height":height}, speed, callback);
});
}
Usage
$(".animateHeight").bind("click", function(e){
$(".test").animateAuto("height", 1000);
});
$(".animateWidth").bind("click", function(e){
$(".test").animateAuto("width", 1000);
});
$(".animateBoth").bind("click", function(e){
$(".test").animateAuto("both", 1000);
});
If you are experiencing a resize issue, where the element is (when resized) bigger than it’s parent, replace:
with:
If you are trying to animate the height on inline elements (like a paragraph), you’ll want to make sure you aren’t changing the width to auto as well. You’ll want to change this line:
to:
as much as I want this to work, I’ve now run into two separate instances where using this doesn’t work. the logic is entirely there – cloning, checking, then animating – but for whatever reason, it’s frustratingly stubborn for me. I either get heights that are way too big, or way too small. I’ve subsequently found two workarounds for this:
the first is to let the content load naturally, grab the heights after the page has loaded, then immediately add a class that would ‘resize’ the box to the desired height. it looks something like this:
the setTimeout lets the web fonts load before taking the heights: it turns out those don’t get loaded until the very end in some browsers, and will give false readings. this also works for positions, similarly avoiding the same pitfall with the setTimeout. then, when the time comes to utilize the heights, simply animate to the given value in the array.
if you can’t assign an index to the element, or if the elements’ content is dynamic, simply give the item you’d like to animate a wrapper, and set it’s overflow to hidden:
then animate the wrapper to the height of the interior element, and it appears to be animating to the given height – dynamically:
I’m sure there are better ways programmatically to go about both of these, but they have worked marvelously for me.
oh, and much love to this site. I hope to one day buy you a beer, Mr. Coyier.
There is an easier way most of the time.
Instead of trying to animate height, animate max-height.
When you want it hidden, max-height:0px does the trick, and when you want it shown, you can animate it to max-height:10000px;…. it will then animate to its normal height.
Just make sure you use max-height instead of height in your transition declaration.