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.