Phase 5 · Modern CSS & EffectsModule 20~30 min read

Transitions & Animations

Bring interfaces to life with smooth transitions, transforms, and keyframe animations.

What you'll learn

Welcome to Phase 5. Motion, used well, makes an interface feel responsive and alive. CSS gives you two tools: transitions for smooth state changes and animations for richer, multi-step motion — all without a line of JavaScript.

By the end you'll be able to:

  • Animate property changes with transition
  • Move and scale elements with transform
  • Build multi-step animations with @keyframes
  • Respect users who prefer reduced motion

Transitions

A transition smoothly animates a property when its value changes — most often on :hover or :focus. You name the property, a duration, and a timing function. Without a transition, changes snap instantly; with one, they glide:

button.css
.button {
  background: #2563eb;
  transition: background 0.2s ease, transform 0.2s ease;
}

.button:hover {
  background: #1d4ed8;
  transform: translateY(-2px);   /* lifts on hover */
}

Tip

Put the transition on the base state (.button), not the :hover — that way it animates both into and out of the hover. Good durations are short: 0.15s–0.3s feels responsive; anything over 0.5s starts to feel sluggish.

Transforms

transform moves, scales, rotates, or skews an element — translate(), scale(), rotate(), skew(). Crucially, transforms don't affect the layout of other elements and are GPU-accelerated, so they're smooth and cheap to animate. Prefer animating transform and opacity over things like width or top, which are far more expensive.

Keyframe animations

For anything beyond a simple A-to-B change, @keyframes defines a sequence of steps, and the animation property plays it. You can set the duration, timing, how many times it repeats (infinite for looping), and direction:

animation.css
@keyframes fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.card {
  animation: fade-in 0.5s ease-out;
}

Here's a looping keyframe animation running live in the preview:

pulse.html
Live preview
A @keyframes animation looping infinitely — real CSS, no JavaScript.

Respecting motion

Motion can cause discomfort or nausea for some people, and operating systems let them ask for less of it. Honour that with the prefers-reduced-motion media query — a mark of a considerate, professional developer:

motion.css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Recap & quick check

Key takeaways

  • transition smoothly animates a property change; put it on the base state, keep it short (0.15–0.3s).
  • transform (translate, scale, rotate) doesn't affect layout and is GPU-accelerated.
  • Prefer animating transform and opacity — they're far cheaper than width or top.
  • @keyframes defines multi-step animations; the animation property plays them (use infinite to loop).
  • Respect prefers-reduced-motion for users who want less movement.

Quick check

1. Where should you declare a transition so it animates both in and out of :hover?

2. Which properties are cheapest and smoothest to animate?

3. What defines a multi-step animation sequence?

4. How do you make an animation loop forever?

5. What does prefers-reduced-motion let you do?

Your interfaces can move now. Next we make CSS smarter and reusable with custom properties and functions.