CSS Transitions, Animations, and Reduced Motion

Animate state changes smoothly and respect users who prefer less motion.

CSS
.button {
  background: #0b5fff;
  transition: background-color 200ms ease, transform 200ms ease;
}
.button:hover {
  background: #0846c4;
  transform: translateY(-2px);
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.4; }
  100% { opacity: 1; }
}
.loading { animation: pulse 1.5s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .button { transition: none; }
  .loading { animation: none; }
}

Explanation

A transition animates a property from its old value to its new value when it changes, for example on hover. Name the properties, the duration, and an easing function. Prefer animating transform and opacity, which browsers can handle smoothly without re-laying out the page. A keyframes animation describes steps over time and is started with the animation property. Some people feel ill from large movements, and their operating system can tell the browser to reduce motion, so a prefers-reduced-motion media query should turn animations off or make them gentle.

Explore the dry run
Guided walkthroughReady
1.button {
2 background: #0b5fff;
3 transition: background-color 200ms ease, transform 200ms ease;
4}
5.button:hover {
6 background: #0846c4;
7 transform: translateY(-2px);
8}
9
10@keyframes pulse {
11 0% { opacity: 1; }
12 50% { opacity: 0.4; }
13 100% { opacity: 1; }
14}
15.loading { animation: pulse 1.5s ease-in-out infinite; }
16
17@media (prefers-reduced-motion: reduce) {
18 .button { transition: none; }
19 .loading { animation: none; }
20}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
When either property changes, it moves to the new value over 200 milliseconds instead of jumping.—
—
The hover state sets the new values that the transition animates towards.—
—
Move the button up by two pixels. transform does not disturb the layout around it.—
—
A named animation described by steps. Here the opacity fades down and back up.—
—
Run the pulse animation every 1.5 seconds, forever.—
—
Applies when the user has asked their system for less motion.—
—
Switch the animation off for those users.—
—