Animations
CSS animations use keyframes to define multi-step motion sequences that can run automatically, repeat, and reverse — going well beyond what a simple transition can do.
Defining Keyframes
@keyframes defines the states an element passes through during an animation, from 0% to 100% (or using from/to for a simple two-state animation).
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card {
animation: fadeInUp 0.6s ease forwards;
}
Controlling Playback
Several properties fine-tune how an animation plays, whether it repeats, and what happens before it starts and after it ends.
animation-iteration-count— a number, or infinite for continuous loops.animation-delay— waits before the animation begins.animation-fill-mode: forwards— keeps the final keyframe's styles applied after the animation completes.animation-direction: alternate— reverses on every other iteration.
Common Mistakes
- Forgetting animation-fill-mode: forwards, causing an element to snap back to its original state once the animation ends.
- Overusing infinite looping animations, which can be distracting and drain battery on mobile devices.
- Animating properties like width/height/top/left instead of transform, which is far more performant for the browser to render.
- Not respecting a user's reduced-motion preference for people sensitive to on-screen movement.
Professional Tip
Wrap non-essential animations in an @media (prefers-reduced-motion: no-preference) query, or provide a reduced version inside @media (prefers-reduced-motion: reduce). This respects users who have asked their operating system to minimise motion.
Your Turn
Create a @keyframes animation that makes a notification badge gently pulse (scale up and down) forever, and a separate one-time fade-in-up animation for cards as they would appear on page load.
Mini Quiz
What does animation-fill-mode: forwards do?
forwards, an element reverts to its pre-animation styles the instant the animation finishes. forwards keeps the last keyframe's state applied.