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.
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.
<custom-ident>
- 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
orinitial
, 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.
Basic Property Information
- Initial Value
auto
- Applies To
- All elements.
- Inherited?
- No
- Media
- All
- Animatable
- No
CSS Specifications
- The
will-change
property is defined in CSS Will Change Module Level 1 (W3C Candidate Recommendation, 03 December 2015).
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.