I have a CSS3 animation that I want to use both in normal and reverse order. I want to trigger the animation by toggling two classes. Basically is an animation that makes an element grow, and I want to use it to shrink the element too.
Basically it is:
The first part works correctly, however if I try to use the same animation for both classes the animation stops working, nothing happens.
div {
max-height: 1em;
width: 50px;
background-color: red;
color: white;
text-align: center;
border-radius: 30px;
padding: 1em 0;
}
.expanded {
animation: expand 2s;
background-color: blue;
}
.collapsed {
background-color: red;
//animation: expand 2s reverse; // Uncomment and all animations stop working
}
@keyframes expand {
0% {
max-height: 1em;
}
50% {
max-height: 1em;
}
100% {
max-height: 200px;
}
}
Here is a simple jsfiddle that demonstrates this: https://jsfiddle.net/danielo515/jxLcoocs/6/
EDIT:
As @LGSon have suggested using a transition property will be simpler for this case example, but I need to use an animation because I am running several animations and I need to be able to delay some parts of them.
The approach you use does not work as the element already has the animation expand
applied, through the class expanded
, so by simply call it again, by adding the class collapsed
, where the only difference is the reverse
, will not work, as they both reference the same animation.
W3 states: In order to restart an animation, it must be removed then reapplied. (https://www.w3.org/TR/css3-animations/#animations)
So the simplest way to make this work is to use 2 different animations, as shown in below sample.
To that sample I also added the animation fill mode forwards
, so it will retain the computed values set by the last keyframe encountered during execution.
Other ways, not shown here, could be:
Remove and reapply the animation, note though, for this to look good the element might need to have its end state applied initially, or else it could jump back on removal
Use animation-play-state
and a script, to pause an animation half way, where the second half does the reverse
Use animation-timing-function
to add steps to the animation
const example = document.getElementById('example');
let expanded = false;
example.className = 'expanded';
const toogleClass = () => {
example.className = expanded ? 'expanded' : 'collapsed';
expanded = !expanded;
}
setInterval(toogleClass, 2500);
div {
max-height: 1em;
width: 50px;
background-color: red;
color: white;
text-align: center;
border-radius: 30px;
padding: 1em 0;
}
.expanded {
animation: expand 2s forwards;
background-color: blue;
}
.collapsed {
background-color: red;
animation: collaps 2s;
}
@keyframes expand {
0% {
max-height: 1em;
}
50% {
max-height: 1em;
}
100% {
max-height: 200px;
}
}
@keyframes collaps {
0% {
max-height: 200px;
}
50% {
max-height: 200px;
}
100% {
max-height: 1em;
}
}
<div id="example">
Hello
<br>
<br>
<br>
<br> Friends
</div>
Another approach would be to use transition
instead, which will give you a much simpler code
const example = document.getElementById('example');
let expanded = false;
setTimeout(function() {example.className = 'expanded';}, 500);
const toogleClass = () => {
example.className = expanded ? 'expanded' : 'collapsed';
expanded = !expanded;
}
setInterval(toogleClass, 2500);
div {
max-height: 1em;
width: 50px;
background-color: red;
color: white;
text-align: center;
border-radius: 30px;
padding: 1em 0;
transition: max-height 2s;
}
.expanded {
background-color: blue;
max-height: 200px;
}
<div id="example">
Hello
<br>
<br>
<br>
<br> Friends
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With