CSS Transitions

Difficulty: Beginner

Question

How do CSS transitions work? What properties can be transitioned?

Answer

CSS transitions animate property changes smoothly over a duration.

Syntax: transition: property duration timing-function delay

Key points: - Only numeric/color properties can transition (width, color, opacity, transform) - display and visibility cannot be smoothly transitioned - Timing functions: ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier() - Performance: only transform and opacity are GPU-accelerated - Put transition on the base state, not the :hover state

Code examples

Transition Basics

/* Transition on base state */
.button {
  background: #3b82f6;
  color: white;
  padding: 0.75rem 1.5rem;
  border-radius: 0.375rem;
  transition: background 0.2s ease,
             transform 0.2s ease;
}
.button:hover {
  background: #2563eb;
  transform: translateY(-2px);
}
.button:active {
  transform: translateY(0);
}

/* Transition all (use sparingly) */
.card {
  transition: all 0.3s ease;
  /* Transitions ANY property that changes */
  /* Can cause unexpected animations */
}

/* Different timing per property */
.element {
  transition:
    opacity 0.3s ease,
    transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

Always put transition on the base state so it animates both on hover and off. Listing specific properties is better than 'all' for performance and predictability.

Timing Functions

/* Built-in timing functions */
.ease     { transition: transform 0.3s ease; }
.linear   { transition: transform 0.3s linear; }
.ease-in  { transition: transform 0.3s ease-in; }
.ease-out { transition: transform 0.3s ease-out; }

/* Custom cubic-bezier */
.bouncy {
  transition: transform 0.5s
    cubic-bezier(0.68, -0.55, 0.265, 1.55);
  /* Overshoots then settles */
}

/* Common custom curves */
.smooth-out {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  /* Material Design standard easing */
}

/* Delay */
.delayed {
  transition: opacity 0.3s ease 0.1s;
  /* 0.1s delay before animation starts */
}

/* Staggered children (with delay) */
.list-item:nth-child(1) { transition-delay: 0.0s; }
.list-item:nth-child(2) { transition-delay: 0.1s; }
.list-item:nth-child(3) { transition-delay: 0.2s; }

ease is the default and works for most cases. Use cubic-bezier for custom physics. Chrome DevTools has a visual curve editor.

Practical Transition Patterns

/* Fade in/out with visibility */
.tooltip {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease,
             visibility 0.2s ease;
}
.trigger:hover .tooltip {
  opacity: 1;
  visibility: visible;
}

/* Slide down menu */
.menu {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
.menu.open {
  max-height: 500px;
  /* Generous max-height, transition handles it */
}

/* Color theme transition */
:root {
  --bg: #fff;
  --text: #111;
}
.dark {
  --bg: #111;
  --text: #fff;
}
body {
  background: var(--bg);
  color: var(--text);
  transition: background 0.3s ease, color 0.3s ease;
}

Use opacity + visibility for show/hide (visibility: hidden is accessible, display: none is not). max-height trick works for expand/collapse.

Key points

Concepts covered

Transitions, Timing Functions, Performance, Hover Effects, Interactive States