CSS will-change

The will-change property allows you to provide hints to the browser regarding what sort of changes it should expect from an element. The browser can then perform any optimizations ahead of time (so so as to avoid a "janky" change or animation).

The will-change property is typically used on elements that you intend to apply CSS transforms or animations to. Without using will-change, you might find that some animations tend to be a bit "jumpy" when they run. For example, you might intend to animate an element when the user hovers over it. You could use the will-change property to ensure the animation runs smoothly.

The following code uses will-change to tell the browser to expect a transform to be applied to the .logo class.

So here's what that might look like with the transform included. In this case, the transform won't occur until the user hovers over the logo.

Therefore, the browser can optimize things so that when the user finally does hover over the logo (if ever), the transform will run smoothly.

In many cases, you might not notice any difference when using the will-change property. This doesn't mean that it doesn't work. Each browser has their own way of handling animations, and therefore, different browsers can use the information provided by will-change in different ways. Your browser might handle an animation fine, whereas another browser could have difficulty. Using will-change should help the browser that has difficulty.

It's also recommended that you toggle will-change using scripting rather than placing it directly into the style sheet. More on this below.

Syntax

Where

Basic Usage

In this example, we tell the browser to expect the value of the left property to change. In this case, will-change is applied to a sidebar that will slide out when the user hovers over it.

I should point out that, it's likely you'll notice little, if any effect of the will-change property in these examples. This is often likely to be true whenever you use this property. Any potential benefits that this property produces will not necessarily be evident across all browsers and devices.

Predicting a Change

It's usually better to use will-change within moments of the actual change, if possible. For example, if an element will change when the user clicks it, you could apply will-change when the user hovers over the element. This will usually provide the user agent enough time to set up its optimizations before the user clicks it.

In the next example, we use the transform property to perform an animation when the user clicks on an element (we do this using the :active pseudo class). The will-change property is applied to the :hover pseudo class, so that it runs when the user hovers over the element. This gives the browser enough time to set up the optimization before the user clicks on it.

Don't Use will-change Too Broadly

It's recommended that you limit the number of properties and elements that you use with the will-change property. Applying will-change too broadly can actually have an adverse impact on performance.

Therefore, it's definitely not a good idea to do this:

The browser already tries to optimize everything, so telling it to optimize everything will either do nothing, or cause problems (e.g. slow down the machine or crash it).

Therefore, the will-change property should only be used on those elements and properties that are actually going to change.

Using will-change in a Script

The will-change specification recommends that in most cases, you toggle the will-change values using a script. This way, you can apply will-change only when needed, then remove it when you're done.

The reason for this is that, whenever you use will-change, the browser will immediately allocate resources to the optimization. If you don't remove will-change, those resources will continue to be allocated to will-change even though you no longer need it. In some cases this could have an adverse impact on performance. So it's preferable that you remove will-change in order to release these resources. By "remove" I mean, set it back to its initial value (auto).

Here's a script that will set will-change as required, then set it back to auto once the animation ends:

This example uses JavaScript's mouseenter event to check for when the user hovers over the element. JavaScript's animationEnd event is fired when the animation has completed.

So in this example, the addHint() function is run when the user hovers over the element, and the removeHint() function is run when the animation has ended.

The function in this example only specifies one property (the transform property). You can also apply multiple properties by separating them with a comma. Like this:

Possible Values

auto

Expresses no particular intent; the user agent should apply whatever heuristics and optimizations it normally does.

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.

Indicates that the author expects to animate or change the property with the given name on the element in the near future. If the property given is a shorthand, it indicates the expectation for all the longhands the shorthand expands to.

In addition, all CSS properties also accept the following CSS-wide keyword values as the sole component of their property value:

initial

Represents the value specified as the property's initial value.

inherit

Represents the computed value of the property on the element's parent.

unset

This value acts as either inherit or initial, depending on whether the property is inherited or not. In other words, it sets all properties to their parent value if they are inheritable or to their initial value if not inheritable.

CSS Specifications

Browser Support

The following table provided by Caniuse.com shows the level of browser support for this feature.

Vendor Prefixes

For maximum browser compatibility many web developers add browser-specific properties by using extensions such as -webkit- for Safari, Google Chrome, and Opera (newer versions), -ms- for Internet Explorer, -moz- for Firefox, -o- for older versions of Opera etc. As with any CSS property, if a browser doesn't support a proprietary extension, it will simply ignore it.

This practice is not recommended by the W3C, however in many cases, the only way you can test a property is to include the CSS extension that is compatible with your browser.

The major browser manufacturers generally strive to adhere to the W3C specifications, and when they support a non-prefixed property, they typically remove the prefixed version. Also, W3C advises vendors to remove their prefixes for properties that reach Candidate Recommendation status.

Many developers use Autoprefixer, which is a postprocessor for CSS. Autoprefixer automatically adds vendor prefixes to your CSS so that you don't need to. It also removes old, unnecessary prefixes from your CSS.

You can also use Autoprefixer with preprocessors such as Less and Sass.