Not all CSS properties animate equally. Understanding the rendering pipeline helps you create smooth 60fps animations.
The Three Layers
Layout Properties (Most Expensive)
Changing these triggers layout recalculation for the element AND its descendants:
/* Triggers Layout + Paint + Composite */
width, height, padding, margin, border
top, left, right, bottom
font-size, line-height
display, position, floatPaint Properties (Medium)
Changing these triggers paint but not layout:
/* Triggers Paint + Composite */
color, background-color, background-image
border-color, border-radius
box-shadow, text-shadow
visibility, outlineComposite Properties (Cheapest)
These go straight to the GPU compositor — no layout or paint:
/* Triggers Composite Only */
transform (translate, scale, rotate)
opacity
filter
will-changePractical Examples
/* Bad: animating width triggers layout on every frame */
.expanding {
transition: width 0.3s;
}
.expanding:hover { width: 200px; }
/* Good: use transform instead */
.expanding {
transition: transform 0.3s;
}
.expanding:hover { transform: scaleX(1.5); }
/* Bad: animating top/left */
@keyframes slide {
to { top: 100px; left: 100px; }
}
/* Good: use translate */
@keyframes slide {
to { transform: translate(100px, 100px); }
}will-change: The Performance Hint
/* Promotes to own compositor layer */
.animated-element {
will-change: transform, opacity;
}
/* Remove after animation */
.animated-element.done {
will-change: auto;
}
/* Don't overuse! Each layer costs GPU memory */
/* Bad: */
* { will-change: transform; }requestAnimationFrame
// Always use rAF for JS animations
function animate() {
element.style.transform = `translateX(${x}px)`;
x += speed;
if (x < target) requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// Never use setInterval for visual updates!Measuring Performance
- Chrome DevTools → Performance → check "Paint flashing"
- Layers panel shows compositor layers and their memory cost
- Rendering tab → FPS meter for real-time monitoring
- Target: 16.67ms per frame (60fps), 6.94ms for 144fps displays