Transitions
When a style changes, for example on mouse hover, the browser switches it instantly. A transition stretches this change over time: a color flows into another, a button grows smoothly. It is the simplest animation in CSS.
The first transition
The transition property names what to animate and how long it takes. Hover over the button:
<style>
.btn { padding: 10px 20px; border: none; background: steelblue; color: white; transition: background 0.4s; }
.btn:hover { background: crimson; }
</style>
<button class="btn">Hover over me</button>Without transition the color would switch with a jerk. Time is written in seconds (0.4s) or milliseconds (400ms).
Parts of a transition
| Property | What it sets | Example |
|---|---|---|
transition-property | Which property to animate | background |
transition-duration | How long it lasts | 0.4s |
transition-timing-function | How the speed changes | ease-in-out |
transition-delay | A pause before the start | 0.2s |
Usually everything is written in one line: transition: background 0.4s ease-in-out 0.2s. The first time is the duration, the second is the delay.
Timing functions
A timing function describes how the speed changes during the transition. Hover over the grey strip — the squares move in different manners:
<style>
.track { padding: 8px; background: whitesmoke; }
.dot { width: 30px; height: 30px; margin: 4px 0; background: mediumpurple; transition: margin-left 1.5s; }
.track:hover .dot { margin-left: calc(100% - 30px); }
.linear { transition-timing-function: linear; }
.in { transition-timing-function: ease-in; }
.out { transition-timing-function: ease-out; }
</style>
<div class="track">
<div class="dot linear"></div>
<div class="dot in"></div>
<div class="dot out"></div>
</div>linear moves evenly, ease-in speeds up, ease-out slows down at the end. The default is ease — a quick start and a soft stop.
Several properties
To animate several properties, list them with commas, each with its own time:
<style>
.card { width: 180px; padding: 16px; background: white; border: 1px solid silver;
transition: box-shadow 0.3s, border-color 0.6s; }
.card:hover { box-shadow: 0 8px 20px rgb(0 0 0 / 0.2); border-color: steelblue; }
</style>
<div class="card">The card lifts up</div>What can be animated
Properties with in-between values change smoothly: sizes, spacing, colors, the opacity transparency, transform. Properties like display switch only as a whole — there is no middle between none and block. Smooth appearing is done with opacity:
<style>
.hint { opacity: 0; transition: opacity 0.5s; }
.area:hover .hint { opacity: 1; }
.area { padding: 12px; background: honeydew; }
</style>
<div class="area">Hover here <span class="hint">— the hint has appeared</span></div>Common mistake
If transition is written only in :hover, the transition works on hover, but when the cursor leaves, the style jumps back: without hover the element has no transition.
<style>
.box { padding: 12px; margin-bottom: 8px; background: lightskyblue; }
.bad:hover { background: gold; transition: background 1s; }
.good { transition: background 1s; }
.good:hover { background: gold; }
</style>
<div class="box bad">Back with a jerk</div>
<div class="box good">Back smoothly</div>Write transition in the main rule of the element — then it works both ways.