CSS/animation
Animation & Keyframes
CSS animations allow multi-step, looping, or complex motion sequences using @keyframes, going beyond what simple transitions can achieve (which only animate between two states).
4 min readcss#css#animation#keyframes
Introduction
CSS animations allow multi-step, looping, or complex motion sequences using @keyframes, going beyond what simple transitions can achieve (which only animate between two states).
Subtopics
@keyframesrule definitionanimation-name,animation-durationanimation-timing-function,animation-delayanimation-iteration-count,animation-directionanimation-fill-mode,animation-play-stateanimationshorthand- Percentage-based keyframe steps vs
from/to
Syntax
css
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-20px); }
100% { transform: translateY(0); }
}
.fade-el {
animation-name: fadeIn;
animation-duration: 1s;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
}
.bounce-el {
animation: bounce 0.6s ease-in-out infinite;
}
.paused {
animation-play-state: paused;
}
@keyframes name { ... }— defines the animation sequence; steps can usefrom/to(equivalent to0%/100%) or explicit percentages for multi-step motion.animation-name— links an element to a defined@keyframessequence.animation-duration— how long one cycle of the animation takes.animation-timing-function— easing curve applied across the animation.animation-delay— wait time before the animation starts.animation-iteration-count— number of times it plays (1,3, orinfinite).animation-direction—normal,reverse,alternate(ping-pongs back and forth each iteration).animation-fill-mode— determines what styles apply before/after the animation runs (forwardskeeps the final keyframe's styles).animation-play-state—runningorpaused, can be toggled (e.g., on hover) to pause an animation.animation— shorthand combining name, duration, timing-function, delay, iteration-count, direction, fill-mode.
Important Properties
| Property | Purpose | Syntax | Example |
|---|---|---|---|
@keyframes | Define animation steps | @keyframes name {} | @keyframes spin {} |
animation-name | Link to keyframes | animation-name: value; | animation-name: fadeIn; |
animation-duration | Cycle length | animation-duration: value; | animation-duration: 2s; |
animation-iteration-count | Repeat count | animation-iteration-count: value; | infinite |
animation-direction | Play direction | animation-direction: value; | alternate |
animation-fill-mode | State before/after | animation-fill-mode: value; | forwards |
animation | Shorthand | animation: name dur timing delay count dir fill; | animation: spin 2s linear infinite; |
Common Use Cases
- Beginner: a fade-in effect on page load using
@keyframes fadeInandanimation-fill-mode: forwards. - Practical UI: a loading spinner using
@keyframes spin { to { transform: rotate(360deg); } }withanimation-iteration-count: infinite. - Real-world: a notification toast that slides in, pauses, then fades out using multiple percentage-based keyframe steps combined with
animation-fill-mode: bothfor clean start/end states.
Common Errors
- ❌
.el { animation: fadeIn 1s; }with no@keyframes fadeIndefined anywhere → ✅ define@keyframes fadeIn { from {...} to {...} }before referencing it, or the animation silently does nothing. - ❌
@keyframes bounce { 0% {...} 50% {...} }missing a100%step, leaving the end state undefined → ✅ always define a clear final step (100%orto) for predictable looping/ending behavior. - ❌ Expecting the element to stay in its final animated state after completion → ✅ add
animation-fill-mode: forwards;— by default, the element reverts to its original (pre-animation) styles once finished. - ❌
animation-iteration-count: unlimited;(invalid keyword) → ✅ the correct keyword isinfinite. - ❌ Animating
top/left/widthfor motion effects, causing janky performance → ✅ animatetransform/opacitywithin@keyframesinstead, since they're GPU-accelerated.
Common Mistakes
- Referencing an
animation-namethat doesn't match any defined@keyframes. - Forgetting
animation-fill-mode: forwardswhen the end state should persist. - Using
unlimitedinstead of the correctinfinitekeyword. - Animating layout-triggering properties instead of
transform/opacity. - Overcomplicating with too many keyframe steps instead of using
animation-timing-functionfor smoother easing.
Quick Reference
css
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.el {
animation: fadeIn 0.6s ease-out forwards;
}
.spinner {
animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
LB
Author
Lakshya Bansal