CSSCSS Transitions Overview

CSS Transitions Overview

A CSS transition smoothly animates a property from one value to another over time, instead of the change happening instantly. Hover a button and its background color used to just snap to the new shade — with a transition, the browser interpolates every frame in between, so the color eases from old to new. Transitions are the simplest way to add motion to a page: no keyframes, no JavaScript, just a hint to the browser that a property change should be animated rather than immediate.

The four core properties

Every transition is built from four ingredients. Each has its own dedicated page — this is the map of how they fit together:

  • transition-property — which CSS property to animate (e.g. background-color, transform, or all).

  • transition-duration — how long the animation takes (e.g. 0.3s).

  • transition-timing-function — the acceleration curve (e.g. ease, linear, cubic-bezier(...)).

  • transition-delay — how long to wait before starting.

A simple worked example

The most common transition: a button whose background eases into a darker shade on hover, instead of flipping instantly.

CSS
.btn {
  background-color: #0066cc;
  color: white;
  padding: 10px 20px;
  border-radius: 6px;
  border: none;

  /* property | duration | timing-function | delay */
  transition: background-color 0.25s ease-in-out 0s;
}

.btn:hover {
  background-color: #004999;
}

Nothing about the :hover rule changed conceptually — the browser still swaps background-color when the pointer enters the button. The transition declaration just tells it to animate that swap over 0.25 seconds instead of applying it in a single frame.

The shorthand vs. longhand

CSS
/* Shorthand: property duration timing-function delay */
.card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* Equivalent longhand */
.card {
  transition-property: transform, box-shadow;
  transition-duration: 0.3s, 0.3s;
  transition-timing-function: ease, ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
}

You can transition multiple properties at once, either by listing several comma-separated property duration timing-function groups, or by using transition: all 0.3s ease to animate everything that changes. all is convenient for quick prototyping, but it also animates properties you didn't intend to (like width from a layout shift), so most production code lists properties explicitly.

What can (and can't) be transitioned

Transitions work by interpolating — calculating intermediate values between a start and end point. That only makes sense for properties with a numeric or otherwise interpolatable value:

  • Numbers and lengthswidth, height, opacity, margin, font-size.

  • Colorscolor, background-color, border-color.

  • Transformstransform (translate, scale, rotate all interpolate smoothly).

  • Shadows and filtersbox-shadow, filter, backdrop-filter.

Not everything can transition
Properties with discrete, non-numeric values — display, visibility (partially — it can flip at 50% but not fade), position, font-family — have no meaningful "in-between" state, so the browser can't interpolate them. Toggling display: none to display: block will always be instant, no matter what transition you attach. To animate an element's appearance/disappearance, transition opacity and transform instead, and use visibility or a delayed display swap only for removing it from the layout/accessibility tree afterward.
Next
Dig into each ingredient: [transition-property](/css/transition-property), [transition-duration & delay](/css/transition-duration), and [timing functions](/css/timing-functions) — or jump ahead to [CSS Animations Overview](/css/animations-intro) for motion that doesn't need a trigger.