user12833286
user12833286

Reputation:

multiple css animations per element doesn't work in Chrome

I'm trying to animate .circle element. It should grow and then shrink after second. So I declared 2 css animations for one element. In Firefox it works great, but in Chrome it doesn't.
Can-i-use shows that animations css rule in Chrome should work too.

Codepen example

Full source code:

*,
*::before,
*::after {
  box-sizing: border-box;
}

@keyframes one {
  100% {
    width: 5000px;
    height: 5000px;
  }
}

@keyframes two {
  100% {
    width: 0px;
    height: 0px;
  }
}

.container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightsalmon;
}

.circle {
  position: absolute;
  height: 0px;
  width: 0px;
  border-radius: 50%;
  background-color: lightgreen;
  /** If declare only one animation, then it will work in Chrome */
  animation: one ease 1s alternate 1 paused, two ease 1s alternate 1 paused;
  animation-fill-mode: forwards;
}
<div class="container">
  <div class="circle"></div>
</div>

<script>
  var circle = document.querySelector(".circle");
  circle.style.animationPlayState = "running, paused";

  setTimeout(() => {
    circle.style.animationPlayState = "paused, running";
  }, 1000);
</script>

Upvotes: 3

Views: 520

Answers (1)

Stephen M Irving
Stephen M Irving

Reputation: 1512

So as one of the comments says, you can do this with a single animation. You should always try to use semantic, meaningful names when coding so I named the animation grow-shrink rather than just one.

*,
::before,
::after {
  box-sizing: border-box;
}

@keyframes grow-shrink {
  50% {
    width: 5000px;
    height: 5000px;
  }
}

.container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightsalmon;
}

.circle {
  position: absolute;
  height: 0;
  width: 0;
  border-radius: 50%;
  background-color: lightgreen;
  animation: grow-shrink 2s;
}

You don't need any of the JavaScript to do this and you don't need the z-index property on .circle. I changed your animation-duration to be 2s rather than 1s since it is doing the work of both 1s animations you had initially. The animation-timing-function initial value is already ease, so I removed that because it is redundant. You also didn't need the alternate value.

If you meant the 1 after alternate in your animation value as the the value for animation-iteration-count then that can be safely removed as that property's initial value is already 1. If you meant it as a 1s delay for the grow animation to start and then another 1s delay for the shrink to start and simply forgot the units then you will have to let me know and I will show you how to modify it to do that. You can easily add the 1s delay for the animation start back in there, but delaying the shrinking would have to be done differently if you use this solution.

Here you can see the Codepen of it working.


🚧 EDIT: Solution #2 🚧

Alternately, if you want to see how to get this done using your method (though I wouldn't recommend it for this particular animation), here is the CSS code after I got your example to work in Chrome (and all other major browsers):

*,
*::before,
*::after {
  box-sizing: border-box;
}

@keyframes grow {
  0% {
    height: 0;
    width: 0;
  }

  100% {
    height: 5000px;
    width: 5000px;
  }
}

@keyframes shrink {
  0% {
    height: 5000px;
    width: 5000px;
  }

  100% {
    height: 0;
    width: 0;
  }
}

.container {
  align-items: center;
  background-color: lightsalmon;
  display: flex;
  height: 100%;
  justify-content: center;
  left: 0;
  position: fixed;
  top: 0;
  width: 100%;
}

.circle {
  animation:
    grow 1s ease-in forwards paused,
    shrink 1s ease-out 1s forwards paused;
  background-color: lightgreen;
  border-radius: 50%;
  height: 0;
  position: absolute;
  width: 0;
}

Go here to see the CodePen of solution #2 working.

Upvotes: 0

Related Questions