CSS Animations & Keyframes
Deep-dive into CSS animations — transitions, @keyframes, timing functions, 8 production-ready animations, rendering pipeline, and performance optimization with interactive demos.
Transitions — The Foundation
Transitions are the simplest way to add motion. They smoothly animate between two states when a property changes — on hover, focus, or class toggle. Understanding transitions is essential before diving into keyframe animations.
Transitions vs Animations
Transitions animate between two states on trigger. Animations run autonomously with keyframes.
🔄 Transitions
- • Animate between 2 states (A → B)
- • Require a trigger (hover, focus, class change)
- • Simple: just add
transitionproperty - • Best for: hover effects, toggles, state changes
🎬 Animations
- • Animate through multiple steps (A → B → C → ...)
- • Run automatically (no trigger needed)
- • Use
@keyframesfor complex sequences - • Best for: loaders, attention grabbers, storytelling
The 4 Transition Properties
transition-propertyWhich CSS properties to animate (all, width, opacity, transform, etc.)transition-durationHow long the transition takes (0.3s, 500ms)transition-timing-functionThe easing curve (ease, linear, ease-in-out, cubic-bezier)transition-delayWait before starting (0s, 200ms)/* Shorthand */
.button {
transition: all 0.3s ease-in-out;
}
/* Longhand */
.button {
transition-property: background-color, transform;
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
transition-delay: 0s;
}Timing Functions — Interactive
Constant speed from start to end
Click "Trigger" to see all easings race side by side
.element {
transition: transform 0.5s linear;
}
.element:hover {
transform: translateX(100%);
}🔑 Key Takeaway: Transitions are the simplest way to add motion to CSS. The timing function controls the acceleration curve. ease-out feels the most natural for UI interactions — fast response, gentle landing.
@keyframes — Multi-Step Animations
While transitions animate between two states, @keyframes let you define animations with multiple steps, complex timing, and autonomous playback. They're the backbone of CSS animation — from loading spinners to page transitions.
@keyframes — Multi-Step Animations
Define named animation sequences with percentage-based stops.
From/To Syntax
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}Percentage Syntax
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-30px); }
100% { transform: translateY(0); }
}The 8 Animation Properties
animation-nameReferences a @keyframes block by name
animation-name: slide;animation-durationLength of one cycle
animation-duration: 1s;animation-timing-functionEasing curve per cycle
animation-timing-function: ease-in-out;animation-delayWait before first cycle
animation-delay: 0.5s;animation-iteration-countHow many times to loop
animation-iteration-count: infinite;animation-directionForward, reverse, or alternate
animation-direction: alternate;animation-fill-modeStyle before/after animation
animation-fill-mode: forwards;animation-play-statePause or resume
animation-play-state: paused;Animation Playground
@keyframes bounce-demo {
0% { transform: translateY(0) scale(1); }
50% { transform: translateY(-40px) scale(1.1); }
100% { transform: translateY(0) scale(1); }
}
.element {
animation: bounce-demo 1.5s ease-in-out
infinite alternate forwards;
animation-play-state: running;
}🔑 Key Takeaway: @keyframes define the animation steps. The animation shorthand combines all 8 properties. Use alternate direction for smooth back-and-forth, forwards fill-mode to keep the final state, and infinite for continuous loops.
8 Essential Production Animations
These are the animations you'll reach for in real projects: fade for reveals, slide for entrances, scale for emphasis, spin for loading, pulse for attention, shake for errors, bounce for playfulness, and shimmer for skeleton screens.
8 Essential CSS Animations
The animations you'll use in 90% of production UIs. Click to preview and copy.
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.element {
animation: fadeIn 0.6s ease-out forwards;
}🔑 Key Takeaway: These 8 animations cover most UI needs: fade for reveals, slide for entrances, scale for emphasis, spin for loading, pulse for attention, shake for errors, bounce for playfulness, and shimmer for skeleton screens.
Animation Performance
Not all CSS properties are equal when it comes to animation performance. Animating width triggers expensive layout recalculation, while transform runs entirely on the GPU. Understanding the rendering pipeline is the key to 60fps animations.
The Rendering Pipeline
Every frame goes through this pipeline. Animating properties higher up the chain is more expensive.
JavaScript
Trigger (requestAnimationFrame, class toggle)
Style
Compute styles for affected elements
Layout
Calculate geometry (width, height, position)
Paint
Fill pixels (colors, shadows, text)
Composite
Combine layers on GPU (transform, opacity)
✅ Best: Composite-Only Animations
Animating transform and opacity skips Layout and Paint entirely — only the GPU Composite step runs. This means 60fps even on slow devices.
transformopacityfilterPerformance Tricks
🚀 will-change
Hint to the browser that a property will change, so it can pre-promote the element to its own compositor layer.
.card:hover { will-change: transform; }
/* Remove after animation completes */
.card { will-change: auto; }⚠️ Don't Overuse will-change
Each will-change element gets its own GPU layer. Too many layers = more memory, more compositing work. Only use it on elements that actually animate.
🎯 prefers-reduced-motion
Respect users who get motion sickness. Always provide a reduced-motion alternative.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}🔑 Key Takeaway: Only animate transform and opacity for 60fps performance. These skip Layout and Paint, running entirely on the GPU. Use will-change sparingly, and always respect prefers-reduced-motion.