How to Pause and Resume CSS Animations
The CSS animation-play-state property provides native
control over the playback of CSS keyframe animations, allowing them to
be paused and resumed on demand without resetting their current
progress. By switching between its two primary values,
running and paused, developers can freeze an
animation at its exact frame and later continue playback seamlessly from
that identical point in time.
The Core Values
The property accepts two primary keyword values:
running: The default state. The animation executes normally according to its defined duration, timing function, and delay.paused: Freezes the animation. The target element remains stationary at the exact visual frame and time offset reached at the moment this value was applied.
How Pausing Works Under the Hood
When a CSS animation runs, the browser tracks its elapsed time and
maps it to the keyframe rules defined in @keyframes. If
animation-play-state: paused is triggered, the browser
immediately stops advancing the internal animation timeline.
Unlike removing an animation class or changing the
animation-name—which resets the animation to its starting
frame (or default styles)—animation-play-state preserves
the element's current computed styles and playback timestamp. The
animation’s cycle, iteration count, and direction remain intact. When
the state is switched back to running, the animation
resumes from the exact millisecond and frame where it was halted.
Implementation Methods
1. Pure CSS (Hover or Focus States)
You can pause animations using CSS pseudo-classes, which is common for elements like rotating carousels, ticker feeds, or continuous background loops.
.animated-box {
animation: slide 5s linear infinite;
animation-play-state: running;
}
.animated-box:hover {
animation-play-state: paused;
}In this setup, hovering over the element halts the animation, and moving the cursor away resumes it from that specific spot.
2. JavaScript Control
For user-driven events, such as a toggle button, JavaScript can modify the inline style or toggle a class that alters the property.
const element = document.querySelector('.animated-box');
function toggleAnimation() {
const currentState = window.getComputedStyle(element).animationPlayState;
element.style.animationPlayState = currentState === 'paused' ? 'running' : 'paused';
}Handling Multiple Animations
If an element has multiple comma-separated animations applied,
animation-play-state can target each one individually by
providing corresponding comma-separated values:
.multi-animated {
animation-name: spin, fade;
animation-duration: 3s, 1s;
animation-play-state: running, paused; /* 'spin' runs, 'fade' is paused */
}If fewer values are provided than there are animations, the browser repeats the list of values to match the total number of running animations.