How to make sure a CSS Animation finishes on time?

Viewed 43

As others have pointed out, CSS animations might get stuck or pause inadvertently because of performance issues, for example a busy JavaScript main thread, like CSS Animation, State change finish animation.

In the context of a webpage using existing third-party libraries or frameworks, we might have no control over the whole web app, so we cannot guarantee that the JavaScript behaves properly.

As there seems to be no way to increase an animation's priority over other browser tasks, and there seems to be no way to decrease the priority of browser tasks initiated by JavaScript so that CSS-initiated tasks are preferred either, and that may have unintended consequences as well, I want to focus on controlling the animation itself.

So, my questions are:

  1. Is there a way to tell the browser, preferably using only CSS, that the animation should rather drop some frames to guarantee to reach the final state in time even if there are performance problems?

  2. If so, can we use CSS animation syntax only, or do we need to use other techniques such as requestAnimationFrame() or complex libraries like GSAP?

Perhaps, there is something like a combination of animation-fill-mode and text-rendering: optimizeSpeed; but to control what to optimize when rendering animations, but I have searched and have not found anything helpful.

What I have tried so far:

.drawer {
    position: fixed;
    left: 100%;
    transition: transform 3s;
    background: blue;
}

.drawer.open {
    transform: translateX(-400px);
  animation-name: slidein;
    animation-duration: 3s;
animation-fill-mode: forwards;
}

@keyframes slidein {
  0%  { transform: none; }
  25% { transform: translateX(-100px); }
  50% { transform: translateX(-200px); }
  75% { transform: translateX(-300px); }
  100%{ transform: translateX(-400px); }
}
<div class="drawer" id="drawer">drawer</div>
<a href="javascript:showDrawer()">show drawer</a>

Although, this is supposed to be a minimal reproducible example, the bug is hard to reproduce when taken out of context. Please try to use CPU throttling in developer tools to see what I mean.

.drawer {
  position: fixed;
  left: 100%;
  transition: transform 3s;
  background: blue;
}

.drawer.open {
  transform: translateX(-400px);
  animation-name: slidein;
  animation-duration: 3s;
}

@keyframes slidein {
  0%   { transform: none; }
  25%  { transform: translateX(-100px); }
  50%  { transform: translateX(-200px); }
  75%  { transform: translateX(-300px); }
  100% { transform: translateX(-400px); }
}
<div>
  <div class="drawer open" id="drawer">drawer</div>
  <a href="javascript:showDrawer()">show drawer</a>
</div>

0 Answers
Related