Xavier_Ex
Xavier_Ex

Reputation: 8810

JQuery/CSS3: Animating auto height change

I need to animate the height of a parent container whenever it changes. The problem is its height is set to auto, and thus the height depends on the content. The end goal I want to achieve is that whenever the height changes due to the content being changed, the change can be animated, either through jQuery or CSS3.

I have searched similar topic but all I found is how to animate the height from a fixed value to "auto" :(

Upvotes: 13

Views: 11791

Answers (3)

rorypicko
rorypicko

Reputation: 4234

You can get the effect you are after with just CSS. instead of animating the height of the div, animate the max-height property. set the max-height on the hover to what you think would be the max-height (be over considerate). the reason for that is, if you set the max-height to 10000px and the height of the div is 1000px and you set the duration of the animation to 1 second it will have cleared the content height after 0.1s and the it will appear asthough the transition is over, as max-height values over 1000px would have no effect. So, a more accurate max-height is better for more consistent animations.

http://jsfiddle.net/2QcCC/2/

.container {
    height: auto;
    min-height: 100px;
    max-height: 100px;
    transition: 1s max-height;
    overflow: hidden;
}
.container:hover {
    max-height: 4000px;   
}

Upvotes: 8

Xavier_Ex
Xavier_Ex

Reputation: 8810

I think I have found a workaround that works relatively nice. For it to work the following requirement has to be satisfied: child element is in the DOM (either loaded with document or dynamically) but hidden.

First I need to calculate the height of the parent as it is in its final state, i.e. with the child already shown. I first came to this method to calculate the height of the hidden child, but this method has a fundamental flaw: if your child's width in some cases is greater than your parent, the contents in the child will be wrapped when it is placed inside the parent. This method will not calculate the height accurately in that case because an absolutely positioned element has no regard to its parent's width.

Thus the only way to accurately calculate the height is to actually place the child inside its parent. Below is the trick:

$(".content").fadeIn(800);
var contentHeight = $(".content").outerHeight(true);
$(".parent").animate({"height", contentHeight}, 200);

I first call fadeIn on the child to put it in the flow of the DOM, and immediately after that grab the height of the child and whatever other things to calculate the proper height the parent should be, and animate the parent's height in a shorter animation span, say .animate({height: myHeight}, 200).

The result is a smoothly animated container with dynamic height depending on its child contents.

Here is the fiddle, as you can see there is no fixed height being set anywhere on the page other than the initial height of the parent container. This fiddle uses CSS3 animations and jQuery, but they are interchangeable in most cases. Notice that you still need the .outerHeight(true) to get the total size of the content including its margins, and setting overflow: hidden on the parent avoids content overflow during animation in some situations.

Upvotes: 1

nullability
nullability

Reputation: 10675

One way to do this is to animate the content height. The parent's height will then follow automatically. Whether this will work for you depends on how the content height is changing but if the content is a fixed height then it should be possible with the following CSS:

.container {
    width: 500px;
    height: auto;
    border: 2px solid blue;
}

.container .content {
    with: 100%;
    height: 200px;
    transition: 1s height;
}

When you change the height of .content with javascript, the height of .container will also be animated.

You can see this in action here: http://jsfiddle.net/MBD6z/

I'm not sure if this will work in your case... I'd need more details on how the content is changing but this is one way of doing it.

Upvotes: 1

Related Questions