Difficulty: Beginner
How do CSS transitions work? What properties can be transitioned?
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
/* 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.
/* 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.
/* 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.
Transitions, Timing Functions, Performance, Hover Effects, Interactive States