An Interactive Guide to CSS Transitions
Part of the series Wobbly Motion
- Share image
Of all the animation tools in our kit, the humble transition property is the one I reach for most. It's small, it's declarative, and when you understand its pieces, it can make an interface feel genuinely delightful.
The fundamentals
Let's start with a button that moves up when hovered:
Without the transition, the button would teleport. With it, the browser interpolates between the two states. transition takes a number of values, but only two are required:
The name of the property we want to animate.
The duration of the animation.
.btn {
transition:
transform 250ms,
opacity 400ms;
}
.btn:hover {
transform: scale(1.2);
opacity: 0;
}Selecting all properties. transition-property accepts all. It saves typing, but I recommend against it: months later, somebody changes an unrelated property and an animation slips through that nobody asked for.
Timing functions
When we move an element from A to B over one second at 60fps, the browser has to work out 60 in-between positions. The timing function decides how they're spaced.
linear
Constant speed from start to finish. It looks robotic for movement, but it's perfect for things that loop forever, like a spinner.
ease-out
Comes in fast, like a ball thrown towards a wall, and gently settles. My default for anything entering the screen.†ease-in is the mirror image, and rarely what you want on its own: it makes things feel sluggish to start.
Custom curves
.springy { transition: transform 500ms cubic-bezier(.34, 1.56, .64, 1);}Hover the track →
Delays
transition-delay is how dropdowns stay open when your cursor slips off for a moment. Add a short delay on the way out, none on the way in:
.menu {
transition: opacity 250ms;
transition-delay: 300ms;
}
.wrapper:hover .menu {
opacity: 1;
transition-delay: 0ms;
}Respect motion preferences
Some people get motion sick. Wrap anything bigger than a fade in a media query:
@media (prefers-reduced-motion: no-preference) {
.btn { transition: transform 250ms; }
}