By the end of this lesson, you will be able to smoothly animate CSS property changes between two states using transitions.
What it is
A CSS transition allows an element to change from one style configuration to another over a specified duration. Instead of snapping instantly to a new state (like changing color on hover), the browser interpolates the values, creating a smooth visual effect. The core mental model is "start state," "end state," and "time to get there." Key related terms include transition-property, transition-duration, transition-timing-function, and transition-delay.
Why it matters
- User Experience: Smooth animations make interfaces feel more responsive and polished rather than abrupt or jarring.
- Visual Feedback: Transitions clearly indicate that an interaction (like hovering or clicking) has been registered by the system.
- Performance: When used correctly (especially with properties like
transformandopacity), transitions are hardware-accelerated and efficient. - Simplicity: They require no JavaScript for basic state changes, keeping code lightweight and maintainable.
Syntax or steps
The most common shorthand syntax combines all four sub-properties into one line. You must define the transition on the base state of the element, not just the hover state.
.selector {
transition: property duration timing-function delay;
}
- Select the element in its default state.
- Add the
transitionproperty. - Specify which CSS property should animate (e.g.,
background-color). - Set how long the animation takes (e.g.,
0.3s). - Define the speed curve (e.g.,
ease-in-out).
Example
Here is a realistic button example that changes background color and scale when hovered.
<style>
.btn {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
/* Define transition on the base state */
transition: background-color 0.3s ease, transform 0.2s ease;
}
.btn:hover {
background-color: #2980b9;
transform: scale(1.05);
}
</style>
<button class="btn">Hover Me</button>
Explanation: The .btn class defines the starting appearance and the rules for animation. We specify two separate transitions: one for background-color lasting 0.3 seconds, and one for transform lasting 0.2 seconds. When the user hovers, the .btn:hover rule applies new values. Because the transition was defined on the base class, the browser animates the change from blue to dark blue and scales the button up smoothly.
Common mistakes
- Defining transition only on :hover: If you put
transitioninside.btn:hover, the element will snap back instantly when the mouse leaves. Always define it on the base selector. - Animating non-animatable properties: Properties like
displayorvisibilitycannot be transitioned directly. Useopacitycombined withpointer-eventsinstead. - Using layout-triggering properties: Animating
width,height, ortop/leftcan cause performance issues because they trigger reflows. Prefertransformandopacityfor better performance. - Forgetting units: Duration must have a unit (e.g.,
0.3sor300ms). A value of0.3without a unit is invalid.
When to use it
Transitions are best for simple state changes triggered by user interaction. For complex sequences or keyframe-based animations, use CSS Animations (@keyframes) or JavaScript libraries.
| Feature | CSS Transitions | CSS Animations (@keyframes) |
|---|---|---|
| Trigger | User interaction (hover, focus, class toggle) | Automatic playback or infinite loops |
| Complexity | Simple start-to-end changes | Multi-step sequences with intermediate states |
| Control | Limited (play/pause via JS) | High (iteration count, direction, fill mode) |
Practice
Guided Exercise: Create a card element that lifts up slightly and casts a larger shadow when hovered. Use transform: translateY(-5px) and box-shadow with a 0.2s ease transition.
Challenge: Modify your previous solution so that the shadow fades out slower than the lift-up motion. Hint: Use comma-separated values in the transition property to set different durations for transform and box-shadow.
Quick check
Question: Why should you define the transition property on the base element selector rather than the pseudo-class (like :hover)?
Answer: Defining it on the base selector ensures the animation occurs both when entering the hover state and when leaving it. If defined only on :hover, the element will animate in but snap back instantly when the mouse leaves.
Summary
CSS transitions provide a simple, performant way to animate state changes based on user interactions. By defining the transition rules on the base element and choosing appropriate properties like transform and opacity, you can create smooth, professional interfaces without JavaScript.