Smoother CSS animations with the will-change property

Published on in CSS and Elsewhere

The will-change property makes the browser render an element with the GPU, which can reduce jankiness and also allows utilizing sub-pixel rendering. But use the property sparingly.

Table of contents

CPU vs GPU

The beginning and ending of CSS animations can sometimes be glitchy because some property transitions (like transform) are rendered with the GPU, whereas the elements are otherwise rendered with the CPU.

I learned about the will-change CSS property from Josh W Comeau's comprehensive article An Interactive Guide to CSS Transitions. From the Hardware acceleration section:

GPUs and CPUs render things slightly differently. [...]

We can fix this problem by adding the following CSS property:

.btn {
  will-change: transform;
}

will-change is a property that allows us to hint to the browser that we're going to animate the selected element, and that it should optimize for this case.

In practice, what this means is that the browser will let the GPU handle this element all the time. No more handing-off between CPU and GPU, no more telltale "snapping into place".

Sub-pixel rendering

There's another benefit to hardware acceleration: we can take advantage of sub-pixel rendering.

Properties like margin-top can't sub-pixel-render, which means they need to round to the nearest pixel, creating a stepped, janky effect. transform, meanwhile, can smoothly shift between pixels, thanks to the GPU's anti-aliasing trickery.

Use will-change sparingly

Note however that you shouldn't overuse the will-change property, like Josh later mentions. It's also mentioned on the will-change page on MDN:

Important: will-change is intended to be used as a last resort, in order to try to deal with existing performance problems. It should not be used to anticipate performance problems.

If everything (every animation or transition) is prioritized, nothing is.