Back to Remotion

Don't use CSS animations in Remotion

packages/docs/docs/troubleshooting/css-animations.mdx

4.0.4701.6 KB
Original Source

The following code does not work in Remotion:

tsx
// ---cut---
const myMarkup = (
  <div
    style={{
      animation: "fadeIn 1s forwards",
    }}
  >
    Hello World!
  </div>
);

Similarly, using transition, @keyframes, or JavaScript-based timers like setTimeout to drive animations is also wrong.

Problem

Remotion renders each frame independently. Frame 30 might be rendered before frame 10, or frame 50 might be rendered twice.
Because CSS animations don't know which frame Remotion is currently rendering, the animation state will be wrong and you'll see:

  • Flickering or blank frames during rendering
  • Incorrect animation progress

Solution

Drive all animations using useCurrentFrame(). This way, the animation state is derived from the frame number and is deterministic.

Here is an example of a fade-in using interpolate():

tsx
// ---cut---
import { AbsoluteFill, interpolate, useCurrentFrame } from "remotion";

export const FadeIn = () => {
  const frame = useCurrentFrame();
  const opacity = interpolate(frame, [0, 30], [0, 1], {
    extrapolateRight: "clamp",
  });

  return (
    <AbsoluteFill
      style={{
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "white",
        fontSize: 80,
      }}
    >
      <div style={{ opacity }}>Hello World!</div>
    </AbsoluteFill>
  );
};

See also