CSS Will Change
In this page:
selector {
will-change: property;
}
What will-change Actually Does
will-change tells the browser to create a new compositor layer for an element ahead of time, so that when the promised property changes, the browser can animate it cheaply without recalculating the whole page layout.
- Only list the specific properties you intend to animate, such as will-change: transform, rather than the vague will-change: auto.
- Accepted values:
- property name — e.g. transform, opacity
- scroll-position — content scrolling is about to change
- contents — the element's contents will change
- auto — no hints (default)
- Use sparingly, only on elements that will animate
- inherit | initial | unset | revert — CSS-wide keywords accepted by every property
Example: What will-change Actually Does
<style>
.box { width: 160px; padding: 20px; background: #cfe8ff; border: 2px solid #1e6fd9; }
.box:hover { transform: scale(1.1); }
.box {
will-change: transform;
}
</style>
<div class="box">Hover me: the browser is told transform will change</div>
When to Use will-change
will-change is most valuable right before a known, upcoming animation, for example just before a modal slides in or a sidebar expands, rather than being applied constantly to every animated element on the page.
- Add will-change through JavaScript just before triggering an animation and remove it once the animation event finishes for the most efficient usage pattern.
- Accepted values:
- will-change: transform — before a transform animation
- will-change: opacity — before an opacity animation
- will-change: auto — remove after the animation
- JavaScript — add it on hover or focus, remove afterward
Example: When to Use will-change
<style>
.modal { width: 200px; padding: 20px; background: #cfe8ff; border: 2px solid #1e6fd9; }
.modal.about-to-open {
will-change: transform;
}
</style>
<div class="modal about-to-open">Modal about to open</div>
Optimizing transform Animations
transform changes, such as translate, scale, and rotate, can run entirely on the compositor thread when will-change is set, keeping animations smooth even while the main thread is busy.
- Prefer transform: translate() over changing top and left for moving elements, since transform can be composited while position changes cannot.
- Accepted values:
- will-change: transform — hints at a transform animation
- transform: translate() | scale() | rotate() — compositor-friendly
- will-change: auto — reset afterward
- note: creates a stacking context and a new layer
Example: Optimizing transform Animations
<style>
.box {
will-change: transform;
transition: transform 0.3s;
background: teal;
color: white;
padding: 12px;
display: inline-block;
}
.box:hover {
transform: translateX(50px);
}
</style>
<div class="box">Runs on the compositor thread</div>
Optimizing opacity Animations
Like transform, opacity can be animated entirely on the compositor thread, making fade transitions on modals, tooltips, and overlays especially good candidates for will-change.
- Combine will-change: opacity with transition: opacity for the smoothest possible fade effects on frequently toggled elements like tooltips.
- Accepted values:
- will-change: opacity — hints at an opacity animation
- opacity: 0 to 1 — the animated range
- will-change: auto — reset afterward
- note: an extra compositor layer is created
Example: Optimizing opacity Animations
<style>
.tooltip {
will-change: opacity;
opacity: 0;
transition: opacity 0.2s;
background: #333;
color: white;
padding: 8px 12px;
display: inline-block;
}
.tooltip.visible {
opacity: 1;
}
</style>
<div class="tooltip visible">Fades smoothly</div>
The Overuse Warning
Because every will-change declaration can create a new GPU-backed layer, marking too many elements consumes significant graphics memory and can paradoxically make scrolling and animations feel slower rather than faster.
- Remove will-change from an element once its animation is complete, either by toggling a class or resetting the property back to auto in JavaScript.
- Accepted values:
- will-change: transform — on a few elements only
- will-change: auto — the default, nothing extra
- avoid * { will-change: ... } — creates too many layers
- remove after use — frees the memory
Example: The Overuse Warning
<style>
.box { width: 160px; padding: 20px; background: #cfe8ff; border: 2px solid #1e6fd9; }
/* Avoid: creates a compositor layer for every element on the page */
* {
will-change: transform;
}
</style>
<div class="box">Every element now gets its own layer (avoid)</div>
- Applying will-change to many elements at once as a blanket performance fix, which can consume excessive memory and actually slow the page down.
- Leaving will-change permanently set on an element long after its animation has finished, wasting browser resources indefinitely.
- Using will-change: contents when the intended change is actually to transform or opacity, mismatched hints provide no benefit.
- will-change hints to the browser that a property is about to change, allowing it to optimize rendering in advance.
- It works best with transform and opacity, since those properties can be animated on the compositor without triggering layout or paint.
- Apply will-change shortly before an animation starts and remove it afterward, overusing it permanently can hurt performance instead of helping.
will-change is supported by all modern browsers; browsers that do not recognize it simply ignore the hint with no negative effect.
Chapter Quiz — Complete all 25 topics to unlock
0/25 topics done
Complete these topics first:
- CSS Container Queries
- CSS Subgrid
- CSS Logical Properties
- CSS Logical Sizing
- CSS Writing Modes
- CSS Aspect Ratio
- CSS Object Fit
- CSS object-position
- CSS Masking
- CSS Math Functions
- CSS Motion Path
- CSS @supports
- CSS @property
- CSS At-Rules
- CSS Cursor
- CSS Will Change
- CSS User Interface
- CSS Print Styles
- CSS Pagination (Print)
- CSS Dark Mode
- CSS Accessibility
- CSS Performance
- CSS Preprocessors
- CSS Frameworks Overview
- CSS Interview Prep