Compositor-only properties: transform, opacity, filter
Why some animations feel buttery, others jank
Browser rendering pipeline: Layout → Paint → Composite. Most CSS property changes trigger Layout (expensive). A few only run on the GPU's compositor (cheap).
Cheap (60fps even on phones):
transform— translateX/Y, rotate, scale, skew.opacity— fade in/out.filter— blur, brightness, hue-rotate.
Expensive (drops below 60fps on phones):
width,height,margin,padding— triggers layout.top,left,right,bottom— triggers layout.box-shadow— triggers repaint.background-color— repaint (lighter than layout, still costs).
The rule
/* BAD — left triggers layout on every frame */
.slide { left: 0; transition: left 0.3s; }
.slide:hover { left: 100px; }
/* GOOD — translateX runs on the compositor */
.slide { transform: translateX(0); transition: transform 0.3s; }
.slide:hover { transform: translateX(100px); }ANY property that can be expressed as a transform should be — the visual result is identical but the performance is 10× better on mobile.
will-change
.modal { will-change: transform, opacity; }Hint to the browser: "promote this to its own GPU layer now." Use SPARINGLY — applying to many elements wastes memory. Best practice: add will-change only just BEFORE animating, remove after.
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.
Sign up — free trial →First 10 lessons in each track are free. No card needed for those.