The problem: changes are abrupt
When a property changes (for example, when hovering with the mouse using :hover), by
default the change is instantaneous: the color jumps abruptly, no warning.
transition makes that change happen in a gradual and smooth way, and the
difference between a hard "snap" and an elegant fade is huge.
.button {
background: #2563eb;
transition: background 0.3s ease;
}
.button:hover {
background: #1e40af; /* the change is animated over 0.3s */
}
Anatomy of transition
The shorthand form accepts several values in this order:
transition: property duration timing-function delay;
/* example: */
transition: transform 0.4s ease-in-out 0s;
- property: what to animate (
background,transform,opacity...) orall. - duration: how long it lasts (
0.3s,200ms...). Required for it to be visible. - timing function (easing): the pace.
ease,linear,ease-in,ease-out,ease-in-out, orcubic-bezier(...). - delay: how long it waits before starting (optional).
Good use with :hover
The practical rule: put the transition on the base state (not on the :hover),
so it animates both on enter and on leave.
.card {
transition: transform 0.2s ease-out;
}
.card:hover {
transform: scale(1.05); /* grows smoothly on mouse hover */
}
⚠️ CLASSIC TRAP: animating expensive properties like
width,heightortopforces the browser to recalculate the layout on every frame, and the effect turns into a stuttery mess. Animatetransformandopacitywhenever you can: they are cheap and smooth as butter.
Examples
A typical transition as a text string
const transition = "transform 0.2s ease-out";
console.log(transition);