Transitions Adv
A CSS transition smoothly animates a property between its old and new value over a set duration, so changes triggered by states like :hover or :focus ease in gradually instead of snapping instantly.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
💡 Think of It Like This
A light switch is instant — on or off. A dimmer switch is a transition : it smoothly changes brightness over time. CSS transitions work the same way — instead of jumping between states (hover, focus), properties glide smoothly. The timing function is like choosing how the dimmer moves: quickly at first, slowly at the end, or at a constant speed.
Understanding CSS Transitions
Without transitions, CSS state changes are instant . Hover a button and its color jumps from blue to dark blue in a single frame. With transition , the browser smoothly interpolates between the old and new values over a specified duration, creating a professional, polished feel.
Transitions require three things: a property to animate (like background-color ), a duration (like 0.3s ), and a trigger (like :hover or :focus ). The transition declaration goes on the base state , not the triggered state — this ensures the animation plays both ways (on hover and on un-hover).
Performance tip: Not all properties animate efficiently. transform and opacity are composited by the GPU and run at 60fps. Properties like width , height , and top trigger layout recalculation (reflow) on every frame and can cause jank.
Transition Syntax Reference
Property
Example
Description
Default
transition-property
transform
Which CSS property to animate
all
transition-duration
0.3s
How long the transition takes
0s
transition-timing-function
ease-in-out
The acceleration curve
ease
transition-delay
0.1s
Wait before starting
transition
all 0.3s ease
Shorthand for all above
—
Basic Transitions
The simplest transition is transition: all 0.3s ease . This animates every property that changes. The example below shows a box that morphs on hover and a bar chart with bouncy easing. Try changing the duration and easing values in the editor.
Timing Functions — The Feel of Motion
The transition-timing-function controls how the transition accelerates. ease starts fast and decelerates. linear moves at constant speed. cubic-bezier() lets you define custom curves — the "bounce" example below overshoots and settles back, creating a playful feel.
Multi-Property & Staggered Transitions
Real-world UIs often animate multiple properties simultaneously, each with its own timing. A card might lift ( transform: 0.3s ), grow a shadow ( box-shadow: 0.4s ), and change border color ( border-color: 0.2s ). Using transition-delay on child elements creates staggered "wave" effects.
Focus States & Accessibility
Transitions aren't just for hover effects — they're essential for focus states too. Animated focus rings make keyboard navigation feel polished and professional. The example below shows input focus transitions, animated nav underlines, and a CSS-only toggle switch. Note the @media (prefers-reduced-motion: reduce) query that disables transitions for users who prefer it.
When to Use Transitions
- Hover/focus feedback — Buttons, links, cards, inputs — every interactive element benefits from smooth state changes.
- Reveal effects — Expanding panels, dropdown menus, tooltip appearances.
- Data visualization — Bar charts, progress bars, gauge indicators.
- Use @keyframes instead when: You need multi-step sequences, looping, or entrance animations — transitions only handle A → B.
⚠️ Common Mistakes
- Transitioning "all" — transition: all 0.3s can cause unexpected animations on properties you didn't intend. Be explicit: transition: transform 0.3s, opacity 0.3s .
- Non-animatable properties — display cannot be transitioned. Use opacity + visibility instead for show/hide effects.
- Forgetting the initial state — The transition must be on the base state, not the :hover state, or it won't animate back when the user un-hovers.
- Animating layout properties — Transitioning width , height , or margin causes reflow on every frame. Use transform: scale() instead.
- Ignoring prefers-reduced-motion — Always wrap transitions in @media (prefers-reduced-motion: reduce) to respect accessibility preferences.
- Too-long durations — Transitions over 0.5s feel sluggish. Keep hover effects at 0.2-0.3s for responsiveness. Reserve longer durations for dramatic reveals.
🎉 Lesson Complete
- ✅ transition smoothly animates between CSS states (hover, focus, class toggle)
- ✅ Timing functions control acceleration — ease, linear, and custom cubic-bezier curves
- ✅ Multiple properties can each have unique durations and delays
- ✅ Always define transitions on the base selector, not the trigger state
- ✅ Use transition-delay with nth-child for staggered wave effects
- ✅ Only transform and opacity are GPU-optimized for 60fps
- ✅ Apply transitions to focus states for polished keyboard navigation
- ✅ Always include @media (prefers-reduced-motion: reduce) for accessibility
Practice quiz
What does a CSS transition do?
- Defines a multi-step looping sequence
- Removes an element from layout
- Smoothly interpolates a property between its old and new value over a duration
- Changes the HTML structure
Answer: Smoothly interpolates a property between its old and new value over a duration. A transition animates the change of a property from one value to another over a set duration, instead of snapping instantly.
What three things does a transition require?
- A property to animate, a duration, and a trigger such as :hover or :focus
- A keyframe, a delay, and a loop
- A class, an id, and a script
- Only a duration
Answer: A property to animate, a duration, and a trigger such as :hover or :focus. You need a property (e.g. background-color), a duration (e.g. 0.3s), and a state change/trigger (like :hover or :focus) to start it.
On which state should the transition declaration be placed?
- On the :hover state
- On the body element only
- It doesn't matter
- On the base (default) state
Answer: On the base (default) state. Putting transition on the base state ensures the animation plays both ways — on hover and on un-hover. On :hover alone it won't animate back.
In the shorthand 'transition: transform 0.3s ease 0.1s', which value is the delay?
- transform
- 0.1s
- 0.3s
- ease
Answer: 0.1s. The shorthand order is property, duration, timing-function, delay — so 0.3s is the duration and 0.1s is the delay.
How does the 'linear' timing function move?
- At a constant speed throughout
- Fast then slow
- Slow then fast
- It overshoots and bounces
Answer: At a constant speed throughout. linear moves at a constant rate. ease (the default) starts fast and decelerates; ease-in starts slow; ease-out ends slow.
What lets you define a custom easing curve, including a bounce that overshoots?
- ease-in-out
- linear
- cubic-bezier()
- steps()
Answer: cubic-bezier(). cubic-bezier() defines a custom acceleration curve; control points outside 0-1 can make it overshoot and settle for a playful 'bounce'.
Which property cannot be transitioned?
- opacity
- display
- transform
- background-color
Answer: display. display is not animatable. For show/hide effects, transition opacity (and toggle visibility) instead.
Which properties are GPU-composited and run smoothly at 60fps?
- width and height
- top and left
- margin and padding
- transform and opacity
Answer: transform and opacity. transform and opacity are composited by the GPU. Animating width, height, top, or margin triggers layout reflow every frame and can cause jank.
What does transition-delay combined with nth-child enable?
- Looping animations
- Staggered 'wave' effects where each child starts slightly later
- Disabling transitions
- Random durations
Answer: Staggered 'wave' effects where each child starts slightly later. Giving each nth-child an increasing transition-delay makes them animate one after another, producing a staggered wave effect.
Why wrap transitions in @media (prefers-reduced-motion: reduce)?
- To speed up rendering
- Because transitions are otherwise invalid
- To respect users who prefer reduced motion for accessibility reasons
- To enable them only on mobile
Answer: To respect users who prefer reduced motion for accessibility reasons. Some users are sensitive to motion; the prefers-reduced-motion media query lets you disable or shorten transitions to honour that accessibility preference.
Continue this course
- Previous: Responsive Images
- Next: Keyframe Animations