transition between undefined heights. jQuery animated for cross-browser support
HTML
<div class="myBox">
<div class="transitionHeightsWrap">
<div class="boxBody">
<p class="p1 p is-active">This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think?</p>
<p class="p2 p">This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think?This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think?This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think? This is really awesome don't you think?</p>
</div>
</div>
</div>
</div>
CSS
.myBox {
background: #eee;
border: 1px solid black;
}
.transitionHeightsWrap {
overflow: hidden;
-webkit-font-smoothing: antialiased;
}
.boxBody {
padding: 20px 0;
}
.p {
padding: 20px;
display: none;
}
.p.is-active {
display: block;
}
JavaScript
var $wrap = $('.transitionHeightsWrap'),
$inner = $wrap.children().first(),
$p1 = $('.p1'),
$p2 = $('.p2'),
$active_p = $p1,
height_on_$wrap;
$wrap.height_int = parseInt($wrap.css('height'), 10);
$inner.height_int = parseInt($inner.css('height'), 10);
$inner.padding_border_height_int = $wrap.height_int - $inner.height_int;
function totalHeight( $el ) {
var padding = parseInt($el.css('padding-top'), 10) + parseInt($el.css('padding-bottom'), 10),
border = parseInt($el.css('border-top-width'), 10) + parseInt($el.css('border-bottom-width'), 10),
height = parseInt($el.css('height'), 10);
return padding + border + height;
}
function transitionTo($p) {
if (transitionTo.transitioning) return;
transitionTo.transitioning = true;
$wrap.css('height', $wrap.height_int + "px");
$wrap.animate({
'height': 0,
'opacity': 0
}, 200, "linear", function() {
$active_p.removeClass('is-active');
$active_p = $p.addClass('is-active');
$wrap.height_int = totalHeight($active_p) + $inner.padding_border_height_int;
$wrap.delay(300).animate({
'height': $wrap.height_int + "px",
'opacity': 1
}, 200, function() {
$wrap.css('height','');
transitionTo.transitioning = false;
});
});
}
transitionTo.transitioning = false;
//TEST
var i = 0;
$('p').on('click', function() {
if (transitionTo.transitioning) return;
++i % 2 ? transitionTo($p2) : transitionTo($p1);
});