Animations & Transitions
Transitions
.btn {
background: #3b82f6;
transition: background 200ms ease-out, transform 150ms ease-out;
}
.btn:hover {
background: #2563eb;
transform: translateY(-2px);
}
What Can Be Transitioned Performantly?
Only transform and opacity are GPU-composited (no layout/paint cost). Avoid transitioning width, height, top, left, margin, padding.
/* Bad — triggers layout */
.box { transition: width 300ms; }
/* Good — GPU composited */
.box { transition: transform 300ms; }
Keyframe Animations
@keyframes slide-in {
from {
opacity: 0;
transform: translateX(-100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.panel {
animation: slide-in 300ms ease-out forwards;
}
animation-fill-mode
| Value | Behavior |
|---|---|
none | Reverts to initial styles after animation |
forwards | Retains final keyframe styles |
backwards | Applies first keyframe styles during delay |
both | Combines forwards + backwards |
will-change
Hints the browser to prepare GPU layers ahead of time:
.animated-card {
will-change: transform, opacity;
}
Use sparingly — excessive will-change increases memory consumption. Remove it after animation completes if possible.
Stacking Context & z-index
A new stacking context is created by:
position: relative/absolute/fixed/sticky+z-indexvalueopacityless than 1transform,filter,perspective,clip-pathisolation: isolatewill-change
/* Create an explicit stacking context to contain z-index */
.modal-overlay {
isolation: isolate;
}
View Transitions API (Modern)
Animate between DOM states or page navigations:
::view-transition-old(root) {
animation: fade-out 200ms ease-out;
}
::view-transition-new(root) {
animation: fade-in 200ms ease-in;
}
document.startViewTransition(() => {
// Update DOM here
});