CSSDebugging Animations in DevTools

Debugging Animations in DevTools

CSS animations and transitions are fundamentally about time, and time is exactly the dimension that's hardest to reason about by staring at a stylesheet. Reading a duration and a cubic-bezier(...) curve on paper tells you almost nothing about how the motion actually feels. Every major browser ships a dedicated Animations panel in DevTools for exactly this reason: it turns invisible, fast-moving timing into a scrubbable, inspectable timeline.

Opening the Animations panel
  • Chrome / Edge: DevTools → the three-dot overflow menu → More tools → Animations (or Ctrl/Cmd+Shift+P and search "Show Animations").

  • Firefox: DevTools → the Animations tab (next to Inspector, Console, etc.).

  • Trigger the animation on the page (hover, click, page load) — it appears in the panel as soon as it starts running.

Every running or recently-run CSS animation and transition on the page is listed as its own row, drawn as a colored bar positioned along a shared timeline. This immediately answers questions that are painful to answer by reading CSS alone: which animations overlap in time, which one starts late, which one is much longer than the others.

Scrubbing frame-by-frame

Click anywhere on the timeline and the panel jumps the live page to that exact moment in the animation — you can drag the playhead back and forth and watch the element interpolate in real time, well slower or faster than the animation would normally run. This is the single most useful feature for animation bugs: instead of squinting at a two-second animation trying to catch a one-frame glitch, you can park the playhead right on top of it.

CSS
/* An animation that "pops" oddly partway through — hard to */
/* diagnose by eye at full speed, easy once you scrub to ~40%. */
@keyframes card-in {
  0% {
    opacity: 0;
    transform: translateY(24px) scale(0.96);
  }
  60% {
    /* overshoot on purpose for a springy feel */
    transform: translateY(-4px) scale(1.02);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.card {
  animation: card-in 480ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
Slowing down playback

Both Chrome and Firefox let you change the overall animation playback rate for the whole page — typically a dropdown offering options like 100%, 25%, and 10% speed. Dropping to 10% turns a snappy 300ms transition into a slow, 3-second-equivalent glide, which is often the only way to actually see whether an easing curve is doing what you think it's doing, or whether a flicker is coming from the animation itself versus something else repainting underneath it.

Inspecting keyframes visually

For a @keyframes animation, the panel's timeline bar shows markers for each keyframe percentage, and clicking a keyframe segment can jump you to its source in the Styles/Sources panel. This turns an abstract set of percentage-based rules into a visual timeline you can step through segment by segment — 0% to 60%, then 60% to 100% — matching exactly how the browser is interpolating between them.

Timing feels off? Look, don't calculate
If an animation feels "off" — too snappy, too sluggish, or with a weird pause — the cause is almost always the `timing-function` or `duration`, not the keyframe values themselves. These are much easier to diagnose by scrubbing the timeline at reduced speed than by mentally simulating a cubic-bezier curve. Try swapping the easing function directly in the Styles panel and re-triggering the animation to compare, live, without touching your CSS file.
Note
The Animations panel only lists CSS animations/transitions and Web Animations API animations — it won't show JavaScript-driven style changes that don't go through either mechanism (e.g. a `requestAnimationFrame` loop that mutates styles directly frame by frame).