In some interface, I want to do animations. Since the transform property is far more optimized for that than other CSS properties, I'll use that.
With transform: scale() : When element aspect ratio doesn't change, no problem. When ratio is supposed to change, the solution I found is to put a container, and in this container an inner. Then apply the opposed transform to the inner block so the ratio look preserved during and after animation.
I did a pen to test the idea, and it works, but with a problem during the animation: the inner block look stretched during animation. I don't get why given that animation time is the same, and easing is linear.
https://codepen.io/AdamElio/pen/PabejP
(Cick on the menu to toggle animation)
document.querySelector('#menu').addEventListener('click', function() {
this.classList.toggle('collapsedd')
});
#menu {
margin: 30px;
padding: 15px;
background: white;
width: 150px;
overflow: hidden;
transform-origin: top center;
transition: transform .5s linear;
}
#menu.collapsedd {
transform: scaleY(.2);
}
#menu .inner {
transition: transform .5s linear;
transform-origin: top center;
}
#menu.collapsedd .inner {
transform: scaleY(5);
}
#menu .inner ul {
padding: 0;
margin: 0;
list-style: none;
}
<nav id="menu">
<div class="inner">
<h5>Menu</h5>
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
</ul>
</div>
</nav>
<div id="transform"></div>
This happens because the counter transform is not the same while the transition is happening. Considering your example, the container will go from scaleY(0.2)
to scaleY(1)
, while the child will go from scaleY(5)
to scaleY(1)
.
At the end and at the beginning of the transition this will work, cause the container and child transforms will "cancel out":
But this is not the case for the intermediate steps of the transition. Consider for example when the transition is 50% complete:
Check the graph below to see how this proportion varies:
The purple line shows the child's scaleY during the transition, the blue line shows the container's scaleY and the dark yellow line shows container scaleY * child scaleY
So, in order to really cancel out the container transform during the transition, you need to use an easing function that holds the expression container scale * child scale = 1
for the whole transition. And that's not an easy task.