Transitions & Animations
@keyframes) let you define multi-step sequences that run automatically or on a loop.
Without transitions, property changes happen instantly — a button turns blue the moment you hover. With transitions, changes animate over time, making your UI feel polished and alive.
The transition Property
Add transition to an element to animate changes to its properties:
.button {
background-color: #6367ff;
transition: background-color 200ms ease;
}
.button:hover {
background-color: #5254e8;
}
The shorthand takes: property duration timing-function delay
transition: all 200ms ease;
transition: background-color 300ms ease-in-out;
transition: transform 200ms ease, opacity 150ms ease;
Timing Functions
transition-timing-function: ease; /* slow start, fast middle, slow end (default) */
transition-timing-function: linear; /* constant speed */
transition-timing-function: ease-in; /* slow start */
transition-timing-function: ease-out; /* slow end */
transition-timing-function: ease-in-out; /* slow start and end */
ease-out feels the most natural for most UI interactions — elements that enter the screen should decelerate as they arrive. Reserve ease-in for elements leaving the screen.
Transitioning Multiple Properties
.card {
transform: translateY(0);
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
transition: transform 200ms ease, box-shadow 200ms ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(99,103,255,0.15);
}
CSS Animations with @keyframes
For more complex, multi-step animations, use @keyframes:
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero {
animation: fadeIn 400ms ease-out forwards;
}
The animation shorthand: name duration timing delay iteration direction fill-mode
Animation Properties
.spinner {
animation-name: spin;
animation-duration: 800ms;
animation-timing-function: linear;
animation-iteration-count: infinite; /* loop forever */
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
Keyframe Percentages
Use percentages to define intermediate steps:
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.notification {
animation: pulse 2s ease-in-out infinite;
}
Reducing Motion
Always respect users who prefer reduced motion — some people experience motion sickness from animations:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Have anything to say about this lesson?
Your feedback helps improve these tutorials. If something was confusing or missing, let us know.