4 Pure CSS3 with JSPublished 2026-10-05Free · no sign-up
Seven demos that explain how CSS @keyframes animations work: a dot following a square path, animation-fill-mode and animation-direction side by side, iteration counts, pausing with play-state, three animations on one element and a reusable keyframe rule that reads custom properties.
A dot travels round the four corners of a square using five keyframes at 0, 25, 50, 75 and 100 percent. It shows the core idea of @keyframes: you describe positions at points in time and the browser fills in everything between.
Four bars run the same two-second animation with a one-second delay and fill-mode none, forwards, backwards and both. Press Run and watch where each bar waits before it starts and where it stays after it ends, which is all fill-mode controls.
var w = document.querySelector('.kf2');
w.querySelector('button').onclick = function () { w.classList.remove('run'); void w.offsetWidth; w.classList.add('run'); };
03. animation-direction Compared
@keyframesdirection
The same left-to-right keyframes played normal, reverse, alternate and alternate-reverse. alternate is the one that makes a loop go back and forth smoothly instead of jumping back to the start, which is why it suits breathing and floating effects.
Three stars spin once, three times and forever after you press Run. animation-iteration-count also accepts fractions, so 2.5 would stop halfway through a third spin; the infinite one keeps going until reduced motion or a pause stops it.
var w = document.querySelector('.kf4');
w.querySelector('button').onclick = function () { w.classList.remove('run'); void w.offsetWidth; w.classList.add('run'); };
05. Pause and Play with play-state
@keyframesplay-state
A spinning disc that pauses exactly where it is and resumes from the same spot, because animation-play-state freezes the animation instead of resetting it. The button is a toggle with aria-pressed and a label that names the next action.
var w = document.querySelector('.kf5'), b = w.querySelector('button');
b.onclick = function () { var p = w.classList.toggle('paused'); b.setAttribute('aria-pressed', p); b.textContent = p ? 'Play' : 'Pause'; };
06. Two Animations on One Element
@keyframesMultiple
An element can run several animations at once by listing them, comma separated, each with its own duration and timing. Here a float, a slow colour change and a gentle tilt combine, and because each animates a different property they never fight.
One @keyframes rule that reads custom properties, so each element can pass its own distance and angle. Three badges slide in from different directions using the same animation, which keeps a design system's motion small and consistent.
A @keyframes rule lists states at percentages of the animation's duration. The browser interpolates everything between them, so a square path needs only five keyframes for its four corners.
fill-mode decides before and after
With a delay, backwards applies the first keyframe while waiting; forwards keeps the last keyframe after the end; both does both. Most entrance animations want both.
Combine without conflict
An element can run several animations at once, comma separated. If each animates a different property, such as translate, rotate and a colour, they combine cleanly.
Reuse with custom properties
Keyframes can read custom properties from the element they run on. One rule with var(--x) serves many elements that each set their own value.
Frequently asked questions
What is the difference between keyframes and transitions?
Transitions animate between two states when something changes; keyframes run their own sequence, can loop and can have many steps.
Can I restart a keyframe animation?
Remove it, force a reflow by reading offsetWidth and add it again, as the Run buttons here do.
Why use the individual translate and rotate properties?
They animate independently, so two animations can move and turn the same element without overwriting each other's transform.