问题
My intent is to animate using CSS3 the transition of height of a element when a child div get expanded.
<div id="container">
<div id="content">
<span>Small Conent</span>
<div id="big">
<p>
This is way bigger content, will be visible after you have clicked the
"Expand" button.
</p>
<p>It should animate up to the correct position.</p>
</div>
</div>
<button id="expand">Expand</button>
</div>
I came up with this hack, using max-height
. But there are a couple of problems:
- The max-height must have a value
- The animation will start and stop according to the
max-height
given value, so if you insert a crazy value like2000px
the animation will have a great delay.
To better illustrate the problem, I created a Fiddle: http://jsfiddle.net/egDsE/3/
The only way of having a precise animation, is to insert the correct value of max-height.
My intention is to calculate using JavaScript (and JavaScript only) what the height of the parent will be once the child is expanded. But of course, I will need to calculate it before the actual transition takes place.
Is this possible? Only pure JS please.
回答1:
Actually, you don't need to do all of the that cloning and stuff...just give the element height auto, check the size and set the height back to 0. It'll happen so fast the browser has no chance to repaint.
Now, this works like a charm, but the thing is that setting the height in Javascript immediately afterward will cause the transition to fail. I just throw a 100ms timeout around it and then it works fine.
Javascript:
document.getElementById('expand').addEventListener('click', function () {
var el = document.getElementById('big');
if (!el.className) {
el.className = 'expanded';
document.getElementById('expand').innerHTML = 'Retract';
var elH = getHeight(el);
window.setTimeout(function() {
el.style.height = elH+'px';
}, 100);
} else {
el.className = '';
el.style.height = '0';
document.getElementById('expand').innerHTML = 'Expand';
}
});
function getHeight(el) {
el.style.height = 'auto';
elHeight = el.offsetHeight;
el.style.height = '0';
return elHeight;
}
CSS:
#container {
border: 1px solid gray;
padding: 20px;
}
#big {
overflow: hidden;
height: 0;
transition: height 0.5s ease-in-out;
-webkit-transition: height 0.5s ease-in-out;
-moz-transition: height 0.5s ease-in-out;
-o-transition: height 0.5s ease-in-out;
}
HTML: no changes to your markup
<div id="container">
<div id="content"> <span>Small Conent</span>
<div id="big">
<p>This is way bigger content, will be visible after you have clicked the "Expand" button.</p>
<p>It should animate up to the correct position.</p>
</div>
</div>
<button id="expand">Expand</button>
</div>
DEMO
回答2:
I have updated the Fiddle with the solution proposed in the comments by Bartdude, optimizing it for performances as possible.
http://jsfiddle.net/egDsE/5/
var calculateHeight = function(e) {
var outside = document.getElementById('outside');
var clone = e.cloneNode(true);
outside.appendChild(clone);
var elHeight = outside.offsetHeight;
outside.removeChild(clone);
return elHeight;
}
The outside div have very basic css:
#outside {
position: absolute;
top: -1000;
left: -1000;
}
I won't recommend this solution if image are involved, they would slow down the operation significantly.
回答3:
not to be that guy but I would use LESS if you don't want to be as intensive and get this functionality
来源:https://stackoverflow.com/questions/24634464/calculate-the-future-height-of-a-element