📌 What Is @keyframes?
The @keyframes at-rule defines the steps of an animation. It tells the browser how an element should change over time—frame by frame. Without @keyframes, CSS animations cannot exist. 🎬✨
🧩 Basic Syntax
Basic @keyframes Structure
@keyframes animationName {
from { /* starting styles */ }
to { /* ending styles */ }
}✔ from is the same as 0%
✔ to is the same as 100%
🎯 Percentage-Based Frames
Percentage Frames
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-30px); }
100% { transform: translateY(0); }
}✔ Use any number of frames (0%, 25%, 50%, 75%, 100%) ✔ More frames = smoother and more complex animations
🎨 Applying Keyframes to an Element
Use with animation properties
.box {
animation-name: bounce;
animation-duration: 1.5s;
animation-iteration-count: infinite;
}✔ The element now follows the defined keyframe steps.
🧪 Multi-Property Animations
Multiple CSS property transitions
@keyframes glow {
0% { opacity: 0.5; transform: scale(1); }
50% { opacity: 1; transform: scale(1.2); }
100% { opacity: 0.5; transform: scale(1); }
}✔ You can animate many CSS properties at once:opacity, transform, color, background, border, filter, clip-path, etc.
🎬 Directional Keyframes
Directional Movement
@keyframes slideRight {
from { transform: translateX(0); }
to { transform: translateX(200px); }
}✔ Works with animation-direction (reverse, alternate, etc.).
✨ Color & Style Animations
Color Change Animation
@keyframes colorShift {
0% { background: red; }
50% { background: blue; }
100% { background: purple; }
}✔ Keyframes can animate colors, shadows, clip-path, filters, borders, spacing, and more.
🔥 Real-World Examples
1️⃣ Fade-In Animation
fadeIn keyframes
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.element {
animation: fadeIn 1s ease-in forwards;
}2️⃣ Loading Spinner
spin animation
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader {
animation: spin 0.8s linear infinite;
}3️⃣ Button Press Effect
press animation
@keyframes press {
0% { transform: scale(1); }
50% { transform: scale(0.9); }
100% { transform: scale(1); }
}
button:active {
animation: press 0.15s ease-out;
}4️⃣ Card Reveal Animation
reveal animation
@keyframes reveal {
0% { opacity: 0; transform: translateY(30px); }
100% { opacity: 1; transform: translateY(0); }
}
.card {
animation: reveal 0.7s ease-out forwards;
}🧠 Advanced Concepts
🎛️ Easing Inside Keyframes
Per-Frame Timing
@keyframes easeSteps {
0% { opacity: 0; animation-timing-function: ease-in; }
50% { opacity: 1; animation-timing-function: ease-out; }
100% { opacity: 0.5; }
}✔ You can change easing at specific frames!
🎞️ Step Animations
Steps keyframe
@keyframes stepsAnim {
from { background-position: 0px; }
to { background-position: -1000px; }
}
.sprite {
animation: stepsAnim 1s steps(10) infinite;
}✔ Perfect for sprite sheets and pixel animations.
🎨 Multiple Keyframes for One Element
Multiple animations
.box {
animation-name: fadeIn, slideRight;
animation-duration: 1s, 2s;
}✔ Lets you combine effects easily.
🛠️ Common Errors & Debugging Tips
- Keyframe name must match animation-name exactly
- Animation must have a non-zero duration to run
- Check for typos in percent markers (like missing %)
- Test with DevTools → Animations panel
- Ensure vendor prefixes only if supporting old browsers
✨ Best Practices
- Use from and to for simple animations
- Use multiple percentage steps for detail and smoothness
- Keep keyframes clean and readable
- Use forwards fill-mode for reveal animations
- Use alternate direction for looping effects