Without transitions, a button that changes colour on hover snaps to the new colour instantly. With one line of CSS, transition: background 0.2s, it fades smoothly instead. Transitions are the easiest way to make a site feel polished and responsive.
They also help people understand what's happening. A menu that slides open shows where it came from, and a button that darkens slightly when pressed confirms the click. Small, quick transitions like these make an interface feel trustworthy without drawing attention to themselves.
How CSS transitions work
A transition animates a property whenever its value changes, usually because of :hover, :focus or a class added by JavaScript. Put the transition on the normal state of the element, so it animates both when the change starts and when it reverses.
.btn { background: navy; transition: background 0.3s ease; }
.btn:hover { background: royalblue; }If you put the transition only on :hover, the effect animates in but snaps back when the mouse leaves, which feels broken.
The four transition properties
| Property | Example | Meaning |
|---|---|---|
transition-property | background, transform, all | What to animate |
transition-duration | 0.3s, 200ms | How long it takes |
transition-timing-function | ease, linear, ease-in-out, cubic-bezier(…) | The speed curve |
transition-delay | 0.1s | How long to wait before starting |
The shorthand is transition: transform 0.2s ease-out 0s;, and you can list several transitions separated by commas.
Avoid transition: all in finished code. It animates every property that changes, including ones you didn't intend, which can cause odd effects and extra work for the browser.
Which properties can be animated?
Anything with in-between values can be transitioned: colours, sizes, opacity, transforms and shadows. Properties like display or font-family can't, because there's no halfway point between none and block.
For the smoothest motion, prefer animating transform and opacity. The browser can handle those on the graphics card without recalculating the layout of the page, so they stay smooth even on slower phones.
Respecting reduced-motion settings
Some people feel unwell when things move on screen, and they can ask their device to reduce motion. You can respect that preference with a media query:
@media (prefers-reduced-motion: reduce) {
* { transition-duration: 0.01ms !important; }
}Colour and opacity changes are usually fine to keep, but large movements and zooms should be toned down or removed.
CSS Transitions Syntax
Transition syntax
.box {
transition: property duration timing-function delay;
transition: transform 0.25s ease, opacity 0.25s ease;
}CSS Transitions Summary
- Transitions animate a property smoothly when its value changes.
- Put the
transitionon the element's normal state, not only on:hover. - Set the property, duration, timing function and optional delay.
transformandopacityanimate most smoothly.- Keep transitions short and respect the reduced-motion setting.
CSS Transitions Examples
Each example runs in the page. Edit the code and press Run to see what changes.
Smooth hover button
Hover over the button. Then delete the transition line and compare.
<button class="btn">Hover me</button>.btn {
padding: 14px 24px;
border: 2px solid #15161b;
border-radius: 12px;
background: #ffd23f;
box-shadow: 0 0 0 #15161b;
font: 700 16px sans-serif;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s;
}
.btn:hover {
transform: translate(-3px, -3px);
box-shadow: 6px 6px 0 #15161b;
background: #ffe066;
}Line-by-line explanation
- Line 9Animate three properties, each over 0.2 seconds. The transition sits on the normal state so it also animates back.
- Lines 12 to 16The hover state: lifted, with a hard shadow.
Comparing timing functions
Hover over the track. All the bars travel the same distance in the same time; only the speed curve differs.
<div class="track">
<div class="bar linear">linear</div>
<div class="bar ease">ease</div>
<div class="bar in">ease-in</div>
<div class="bar out">ease-out</div>
<div class="bar bounce">bounce</div>
</div>.track { padding: 10px; background: #f3ede2; border-radius: 12px; }
.bar {
width: 90px;
margin: 6px 0;
padding: 6px;
background: #4467ff;
color: white;
font: 12px monospace;
border-radius: 6px;
transition: transform 1.2s;
}
.track:hover .bar { transform: translateX(200px); }
.linear { transition-timing-function: linear; }
.ease { transition-timing-function: ease; }
.in { transition-timing-function: ease-in; }
.out { transition-timing-function: ease-out; }
.bounce { transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }Line-by-line explanation
- Line 10Each bar moves over 1.2 seconds.
- Line 12Hovering the track moves every bar.
- Line 18A custom curve that overshoots and settles, giving a playful "bounce".
Common CSS Transitions Mistakes
Transition on the hover state only
.card:hover { transform: scale(1.05); transition: transform 0.3s; }.card { transition: transform 0.3s; }
.card:hover { transform: scale(1.05); }With the transition only on :hover, it animates in but snaps back out.
transition: all on everything
* { transition: all 0.5s; }.btn { transition: background-color 0.2s, transform 0.2s; }all animates things you didn't mean to (like layout changes when the window resizes) and can hurt performance.
CSS Transitions in Real Projects
Micro-interactions
Buttons that lift, cards that grow, menus that fade in, toggles that slide and focus rings that glow: these small transitions are called micro-interactions, and well-designed apps are full of them. On this site, the cards and buttons you hover use transitions of about 150 to 200ms.
CSS Transitions Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Animate the opacity over 0.3 seconds.
.photo {
: opacity ease;
}
.photo:hover { opacity: 0.7; }
transition: property duration timing-function.Where should you put the transition property?
Which properties are cheapest to animate smoothly?
The link's colour should fade over 0.25s both on hover and when the mouse leaves. Fix the CSS.
<a class="link" href="#">Read more</a>.link {
color: #4467ff;
}
.link:hover {
color: #f0592b;
transition: colour 0.25s;
}- The transition is on the normal state
CSS Transitions Quiz
3 questions to check what you learned.
What does
transition-duration: 300msmean?- 3 seconds
- 300 frames
- 30 seconds
- 0.3 seconds
Can you transition
display: nonetodisplay: block?- Yes, it fades
- No.
displayhas no in-between values, so fadeopacityinstead - Only with ease-in
- Only on hover
Which timing function starts slow and speeds up?
- ease-in
- ease-out
- linear
- step-end
CSS Transitions Challenge
Lift-on-hover card
Make .card:
- Have
transition: transform 0.2s ease, box-shadow 0.2s ease - On hover, move up with
transform: translateY(-6px) - On hover, gain a
box-shadow
<div class="card">
<h3>Sunset Sneakers</h3>
<p>£65</p>
</div>.card { width: 200px; padding: 16px; border: 2px solid #15161b; border-radius: 14px; background: white; font-family: sans-serif; }
- Transition on transform and box-shadow
- Duration 0.2s
- Hover rule moves the card up 6px
- Hover rule adds a shadow