CSS Animations: Keyframes and Motion for Dynamic Interfaces
What Are CSS Keyframe Animations?
While CSS transitions handle simple state changes (like hover effects), CSS animations let you create complex, multi-step animations using @keyframes. Animations can run automatically, repeat infinitely, and animate through multiple stages.
The @keyframes Rule
The @keyframes rule defines the stages of an animation. You specify what styles should apply at different points during the animation:
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}You can also use percentages for more control:
@keyframes slideAndFade {
0% {
opacity: 0;
transform: translateY(-20px);
}
50% {
opacity: 0.5;
transform: translateY(-10px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}Applying Animations
Use the animation-name property to connect an element to your keyframes:
.hero-title {
animation-name: fadeIn;
animation-duration: 1s;
}Animation Properties
CSS provides several properties to control animation behavior:
animation-duration
Sets how long the animation takes to complete one cycle:
.box { animation-duration: 2s; }animation-timing-function
Controls the acceleration curve of the animation:
.box { animation-timing-function: ease-in-out; }Common values: ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier()
animation-delay
Sets a delay before the animation starts:
.box { animation-delay: 0.5s; }animation-iteration-count
Defines how many times the animation repeats:
.spinner { animation-iteration-count: infinite; }
.bounce { animation-iteration-count: 3; }animation-direction
Controls whether the animation plays forward, backward, or alternates:
.pulse {
animation-direction: alternate;
/* normal | reverse | alternate | alternate-reverse */
}animation-fill-mode
Determines what styles are applied before and after the animation:
.fade-in {
animation-fill-mode: forwards;
/* none | forwards | backwards | both */
}- forwards: Element keeps the final keyframe styles after animation ends
- backwards: Element gets the first keyframe styles during the delay period
- both: Applies both forwards and backwards behavior
animation-play-state
Pauses or resumes an animation:
.box:hover {
animation-play-state: paused;
}The Animation Shorthand
You can combine all animation properties into one shorthand:
/* animation: name duration timing-function delay iteration-count direction fill-mode */
.element {
animation: fadeIn 1s ease-in-out 0.5s 1 normal forwards;
}A simpler common pattern:
.element {
animation: fadeIn 0.3s ease-out forwards;
}Practical Animation Examples
Loading Spinner
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #ddd;
border-top-color: #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}Bounce Effect
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.bounce-icon {
animation: bounce 2s ease-in-out infinite;
}Pulse Effect
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.pulse-button {
animation: pulse 2s ease-in-out infinite;
}Slide In from Left
@keyframes slideInLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.sidebar {
animation: slideInLeft 0.5s ease-out forwards;
}Multiple Animations
You can apply multiple animations to a single element by separating them with commas:
.element {
animation:
fadeIn 0.5s ease-out forwards,
slideUp 0.5s ease-out forwards;
}Animation Performance Tips
For smooth 60fps animations, follow these guidelines:
- Only animate transform and opacity — these properties are GPU-accelerated
- Avoid animating width, height, margin, padding, top, left — these trigger layout recalculations
- Use will-change sparingly to hint the browser about upcoming animations
/* GOOD: GPU-accelerated, smooth */
@keyframes move {
to { transform: translateX(100px); }
}
/* BAD: Triggers layout, janky */
@keyframes move {
to { left: 100px; }
}Accessibility: Respecting User Preferences
Some users experience discomfort with animations. Use the prefers-reduced-motion media query to respect their preferences:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}Summary
CSS keyframe animations allow you to create rich, multi-step animations using @keyframes rules and animation properties. Use the shorthand property for concise code, animate only transform and opacity for performance, and always respect user preferences with prefers-reduced-motion. Animations add life to your interfaces when used thoughtfully and sparingly.