Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
550 views
in Technique[技术] by (71.8m points)

css - Can't use the same animation in reverse for class toggle

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:

  • add expanded class: execute animation
  • Remove expanded class, add collapsed class: execute animation in reverse

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...