13

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" :(

Xavier_Ex
  • 8,432
  • 11
  • 39
  • 55

3 Answers3

8

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;   
}
sigod
  • 3,514
  • 2
  • 21
  • 44
rorypicko
  • 4,194
  • 3
  • 26
  • 43
  • Thank you for your answer, but as I mentioned above the parent has dynamic height and the content has dynamic height as well, so there is unfortunately no height being set in CSS or anything. I would try to avoid setting max-height because in theory the child's height can go from very small to very big. Plus, I did not find your fiddle demonstrating max-height anywhere. I tried working up an example with max-height: http://jsfiddle.net/MBD6z/4/ but nonetheless it doesn't look quite right. – Xavier_Ex Jun 10 '13 at 21:47
  • 1
    wait what? i didn't save the fiddle! :( haha here ya go. http://jsfiddle.net/2QcCC/2/ – rorypicko Jun 10 '13 at 22:13
  • Aha now I see it. Even though I would avoid estimating max-height in my situation, this is still a good demo of the max-height trick with accurate and inaccurate estimation. This is no doubt an easier approach that works in simpler cases, but I still prefer the solution that I found since it performs the animation more consistently. – Xavier_Ex Jun 10 '13 at 22:23
  • 1
    Yeah, you're solution works better! although I would suggest adding `.stop(true, true).` before the fadeOut(200) to stop the animations from queuing up. in your example http://jsfiddle.net/MBD6z/5/ if oyu hover in and out of the div, the content keeps fading in an out. see http://jsfiddle.net/MBD6z/6/ I learned that one recently! – rorypicko Jun 10 '13 at 22:31
  • Damn, that was a very long sentence in the answer. – Sebastian Barth Sep 15 '18 at 22:32
1

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.

nullability
  • 10,545
  • 3
  • 45
  • 63
  • Thanks for the answer, but my content is also dynamic height. I assume this will not work in my case then. – Xavier_Ex Jun 10 '13 at 19:07
1

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.

Community
  • 1
  • 1
Xavier_Ex
  • 8,432
  • 11
  • 39
  • 55
  • This answer worked great for me, but how do I deal with the parent having multiple children whose heights I need to calculate? Should I just step through the parent's children and add all their heights? If so how do I this? – David Jul 28 '15 at 04:55
  • 1
    I solved my own problem, the way to do it is: At the beginning of the height change function compute the current height of the parent using .height(), then just compute the change in height needed by getting the .outerHeight of new elements, subtracting the .outerheight of ones that are being hidden, and compute the differences between ones that are being replaced and then add or subtract those differences from the parent's height. There really should be a way to just tell the browser to animate any dynamic changes in the DOM. – David Jul 28 '15 at 20:03