CSS will-change Property: When and When Not to Use It

Paul Ryan

The will-change CSS property is commonly misunderstood or not used correctly, in this short post I will demystify the property so you can make your CSS animations and transitions as performant as possible.

What is will-change?

In a nutshell, the will-change property is a way to tell the browser ahead of a time which properties and elements are likely to be manipulated. Using this information, the browser can make optimizations before they are needed which can result in a smoother experience.

An example of this would be if we were applying a transform on an element we could inform the browser of this like so:

will-change: transform;

You can also declare multiple values like so:

will-change: transform, opacity;

will-change Values

will-change can take four possible values:

  • auto - browser will apply the optimizations
  • scroll-position - indicates that the author expects to animate or change the scroll position of the element in the near future
  • contents - indicates that the author expects to animate or change something about the element’s contents in the near future.
  • custom-indent - indicates that the author expects to animate or change the property with the given name on the element in the near future.

The value we’re going to focus on is custom-indent i.e. transform, opacity, etc.

When to use will-change?

As stated by Mozilla’s MDN, will-change should be used as a last resort.

If we abuse the usage of will-change, we will suffer performance hits which is the exact opposite of what we want. If your animations/transitions are smooth and crisp then there is no need to use will-change. The browser is already making optimizations without the use of will-change.

Don’t do this!

A common mistake people make when using will-change is this:

.my-element:hover {
  will-change: opacity;
  transition: opacity .25s ease-in-out;
}

This is doing more harm than good, will-change is future tense so it shouldn’t be applied when the animation is happening.

A better use of will-change here would be to put the will-change on the parent of my-element like so:

.parent-element:hover {
  will-change: opacity;
}

.my-element:hover {
  transition: opacity .25s ease-in-out;
}

This lets the browser know ahead of time to optimize for this change. Remember to use this as a last resort if your animations are janky or flickering.

Removing will-change

It is recommended by Mozilla to remove will-change after the element is done changing. This is why it’s also recommended to set will-change via JavaScript so you can remove it. If will-change is set in the CSS stylesheet, it can not be removed.

Code-wise this is quite simple and looks like this:

const el = document.querySelector('.parent-element')
el.addEventListener('mouseenter', addWillChange)
el.addEventListener('animationend', removeChange)

const addWillChange = () => {
  this.style.willChange = 'opacity'
}

const removeChange = () => {
  this.style.willChange = 'auto'
}

The code above is very simple, we’re adding our will-change to the parent-element when it is hovered then when the animationend event is fired we then remove our will-change.

Setting will-change in a stylesheet can make sense in some circumstances. A circumstance such as this would be an element that is likely to be interacted with multiple times, this could be something like a ripple effect on a button or a sidebar sliding out. Generally, there should only be a handful of will-change properties in a stylesheet, the rest should ideally be set through JavaScript.

Conclusion

This was a short little introduction to will-change, and if you’re looking to dive deeper I would really recommend checking out Sara Soueidan’s great article on the topic.

Thanks for reading!

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#