Save the current height:
var curHeight = $('#first').height();
Temporarily switch the height to auto:
$('#first').css('height', 'auto');
Get the auto height:
var autoHeight = $('#first').height();
Switch back to curHeight
and animate to autoHeight
:
$('#first').height(curHeight).animate({height: autoHeight}, 1000);
And together:
var el = $('#first'),
curHeight = el.height(),
autoHeight = el.css('height', 'auto').height();
el.height(curHeight).animate({height: autoHeight}, 1000);
IMO this is the cleanest and easiest solution:
$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000 );
Explanation: The DOM already knows from its initial rendering what size the expanded div will have when set to auto height. This property is stored in the DOM node as scrollHeight
. We just have to fetch the DOM Element from the jQuery Element by calling get(0)
and then we can access the property.
Adding a callback function to set the height to auto allows for greater responsiveness once the animation is complete (credit chris-williams):
$('#first').animate({
height: $('#first').get(0).scrollHeight
}, 1000, function(){
$(this).height('auto');
});
This is basically the same approach as the answer by Box9 but I wrapped it in a nice jquery plugin that takes the same arguments as a regular animate, for when you need to have more animated parameters and get tired of repeating the same code over and over:
;(function($)
{
$.fn.animateToAutoHeight = function(){
var curHeight = this.css('height'),
height = this.css('height','auto').height(),
duration = 200,
easing = 'swing',
callback = $.noop,
parameters = { height: height };
this.css('height', curHeight);
for (var i in arguments) {
switch (typeof arguments[i]) {
case 'object':
parameters = arguments[i];
parameters.height = height;
break;
case 'string':
if (arguments[i] == 'slow' || arguments[i] == 'fast') duration = arguments[i];
else easing = arguments[i];
break;
case 'number': duration = arguments[i]; break;
case 'function': callback = arguments[i]; break;
}
}
this.animate(parameters, duration, easing, function() {
$(this).css('height', 'auto');
callback.call(this, arguments);
});
return this;
}
})(jQuery);
edit: chainable and cleaner now
A better solution would not rely on JS to set the height of your element. The following is a solution that animates a fixed height element to full ("auto") height:
var $selector = $('div');
$selector
.data('oHeight',$selector.height())
.css('height','auto')
.data('nHeight',$selector.height())
.height($selector.data('oHeight'))
.animate({height: $selector.data('nHeight')},400);
https://gist.github.com/2023150
this is working and it is simplier then solutions before:
CSS:
#container{
height:143px;
}
.max{
height: auto;
min-height: 143px;
}
JS:
$(document).ready(function() {
$("#container").click(function() {
if($(this).hasClass("max")) {
$(this).removeClass("max");
} else {
$(this).addClass("max");
}
})
});
Note: This solution requires jQuery UI
var h = document.getElementById('First').scrollHeight;
$('#First').animate({ height : h+'px' },300);
You can always wrap the child elements of #first and save height height of the wrapper as a variable. This might not be the prettiest or most efficient answer, but it does the trick.
Here's a fiddle where I included a reset.
but for your purposes, here's the meat & potatoes:
$(function(){
//wrap everything inside #first
$('#first').children().wrapAll('<div class="wrapper"></div>');
//get the height of the wrapper
var expandedHeight = $('.wrapper').height();
//get the height of first (set to 200px however you choose)
var collapsedHeight = $('#first').height();
//when you click the element of your choice (a button in my case) #first will animate to height auto
$('button').click(function(){
$("#first").animate({
height: expandedHeight
})
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With