Waiting for animation to complete

I am trying to animate the height of elements using css. As I do this, I have added a touch element to the element. The function adds className to the element that should hide, i.e. Get height 0.

The problem is that when you click on a div element that supposedly gets a height of 0, the pause per second then gets the desired height. It seems that the longer the animation, the longer it waits until it comes to life.

Here is the relevant code:

 transition: max-height 2s ease-in-out; 

Jsfiddle

 var heading = document.getElementById('heading'), body = document.getElementById('body'); heading.addEventListener('click', hide); body.addEventListener('transitionend', hideCallback); function hide() { body.className = 'hide'; } function hideCallback(e) { console.log(e.propertyName); } 
 #wrapper { margin: auto; background-color: blue; width: 470px; text-align: center; overflow: hidden; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17); max-height: 400px; max-width: 600px; padding: 0; } #buttonContainer { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; align-content: center; flex-direction: column; margin: auto; width: 100px; height: 100px; color: white; } #buttonIcon { width: 36px; height: 36px; line-height: 36px; font-size: 35px; font-weight: bold; display: inline-block; } #buttonLabel { font-size: 20px; } #content { width: 100%; height: 100%; text-align: left; transform: translateY(0px); } #heading { color: white; text-align: right; margin: 10px; font-size: 17px; } #body { color: #000; color: rgba(0, 0, 0, 0.87); background-color: #FFF; width: 100%; max-height: 500px; padding: 10px 0; box-sizing: border-box; } #body.hide { transition: max-height 2s ease-in-out; max-height: 0; } #innerBody { height: 200px; background-color: orange; } 
 <div id="wrapper"> <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span> </div> <div id="content"> <div id="heading">Press Me</div> <div id="body"> <div id="innerBody"></div> </div> </div> </div> 
+6
source share
3 answers

You are max-height animations, not height . The max-height animation is a trick that is used to animate the height of elements with an unknown height. You specify a very large max-height , and while the unknown height is less than the maximum height, it works. The only drawback is that since your animation process is larger than your actual height, it will have a delay. In this case, your max-height is 500 pixels, and the height (including indentation) is only 220 pixels, which means that more than the time (~ 1.1 sec), it simply reduces the maximum height to 220 pixels, and when it goes there gets the visual starts to revive.

If, like this example, you know the actual height of the element (220 = padding 10 + innerBody height 200), you can animate the exact height.

If you don’t know the height in advance, try lowering the max-height estimates and use acceleration that starts quickly, such as ease-out , or use javascript to set the height of the beginning and end.

Known height: 220px (watch in full screen ):

 var heading = document.getElementById('heading'), body = document.getElementById('body'); heading.addEventListener('click', hide); body.addEventListener('transitionend', hideCallback); function hide() { body.className = 'hide'; } function hideCallback(e) { console.log(e.propertyName); } 
 #wrapper { margin: auto; background-color: blue; width: 470px; text-align: center; overflow: hidden; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17); max-height: 400px; max-width: 600px; padding: 0; } #buttonContainer { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; align-content: center; flex-direction: column; margin: auto; width: 100px; height: 100px; color: white; } #buttonIcon { width: 36px; height: 36px; line-height: 36px; font-size: 35px; font-weight: bold; display: inline-block; } #buttonLabel { font-size: 20px; } #content { width: 100%; height: 100%; text-align: left; transform: translateY(0px); } #heading { color: white; text-align: right; margin: 10px; font-size: 17px; } #body { color: #000; color: rgba(0, 0, 0, 0.87); background-color: #FFF; width: 100%; height: 220px; padding: 10px 0; box-sizing: border-box; } #body.hide { transition: height 2s ease-in-out; height: 0; } #innerBody { height: 200px; background-color: orange; } 
 <div id="wrapper"> <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span> </div> <div id="content"> <div id="heading">Press Me</div> <div id="body"> <div id="innerBody"></div> </div> </div> </div> 

Unknown height with javascript - set the actual height before starting the animation, wait for the next frame and change it to 0 (see in full screen mode ):

 var heading = document.getElementById('heading'), body = document.getElementById('body'); heading.addEventListener('click', hide); body.addEventListener('transitionend', hideCallback); function hide() { body.style.height = body.scrollHeight + 'px'; /** sample actual height, and set it on element **/ requestAnimationFrame(function() { // wait for next frame body.style.height = 0; // change height to 0 }); } function hideCallback(e) { console.log(e.propertyName); } 
 #wrapper { margin: auto; background-color: blue; width: 470px; text-align: center; overflow: hidden; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17); max-height: 400px; max-width: 600px; padding: 0; } #buttonContainer { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; align-content: center; flex-direction: column; margin: auto; width: 100px; height: 100px; color: white; } #buttonIcon { width: 36px; height: 36px; line-height: 36px; font-size: 35px; font-weight: bold; display: inline-block; } #buttonLabel { font-size: 20px; } #content { width: 100%; height: 100%; text-align: left; transform: translateY(0px); } #heading { color: white; text-align: right; margin: 10px; font-size: 17px; } #body { color: #000; color: rgba(0, 0, 0, 0.87); background-color: #FFF; width: 100%; padding: 10px 0; box-sizing: border-box; transition: height 2s ease-in-out; } #innerBody { height: 200px; background-color: orange; } 
 <div id="wrapper"> <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span> </div> <div id="content"> <div id="heading">Press Me</div> <div id="body"> <div id="innerBody"></div> </div> </div> </div> 
+2
source

Your initial max-height set to 500 pixels, but the actual height is much smaller. Upon transition, this 500px gradually decreases to 0. At first, it has no visual effect until the maximum height is less than the actual height. this causes the delay you see.

You should either translate the actual height property to 0 (but this only works if the initial height is set to 200 pixels in your case). Or you can look at the transform: scaleY(0) transition, which has the added benefit of being much cheaper and giving much smoother animations. ( http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/ )

+2
source

try another CSS transition-timing-function like linear or ease-out .

According to w3schools ,

ease-in-out Determines the transition effect with a slow start and end (equivalent to a cubic mirrorless (0.42,0,0,58,1))

0
source

All Articles