force3D
force3D is the GSAP property that forces an animated element onto its own GPU layer by applying a 3D transform matrix even when the animation is 2D-only. Without it, browsers may skip the layer promotion and animate on the main thread, causing jank. GSAP enables it by default for transform-based animations; understanding when (and when not) to override matters for memory-tight pages.
Updated June 2, 2026
How force3D works
Browsers composite elements with 3D transforms on the GPU. Elements with 2D-only transforms (translate, scale, rotate) sometimes get the same treatment, sometimes don't - the decision depends on the browser's heuristics. force3D: true adds a no-op 3D component (typically translateZ(0)) to guarantee GPU compositing.
Use force3D for
- Any GSAP transform animation (GSAP enables it by default - leave it on)
- Heavy compositing scenes (parallax with multiple layers) where you need predictable GPU promotion
- Animations that mix opacity + transform where you want the whole element on its own layer for the duration
- Anywhere you see jank during animation and the element isn't already promoted via CSS
will-changeortransform
Use something else when
- Memory pressure on mobile - too many force3D layers can exhaust mobile GPU memory; opt out per-tween (
force3D: false) - Tight CSS-driven systems where you've already promoted via
will-change: transformortransform: translateZ(0)- the JS-level force3D is redundant - Non-transform animations (CSS variables, scroll position) - force3D has no effect, omit it
- After the animation completes - GSAP auto-removes the 3D promotion when the tween ends, freeing the layer
Used in these Annnimate components
- The Parallax component relies on force3D being on so each layer composites on its own GPU layer during the scrub
- The Multi Flip explicitly sets force3D: true on the card transforms so the whole flip animates on the GPU regardless of browser heuristics
- The Magnetic Button uses force3D on the pointer-tracking translate so the hover motion never jitters from main-thread layout
- The Popping Text relies on force3D for each character's per-letter transform - 50+ chars on a hero would jank without GPU promotion
See it running in production
Common questions
- Do I need to set force3D manually if GSAP enables it by default?
- Usually no. GSAP sets
force3D: 'auto'by default for transform tweens, which adds the 3D matrix on tween start and removes it on tween complete. Manual control matters when (1) you want to opt OUT for memory reasons or (2) you want to opt IN for non-transform tweens that benefit from layer promotion. - Why does GSAP remove force3D when the tween ends?
- Permanent GPU layers cost memory. GSAP's default
'auto'mode promotes the element to GPU during the animation, then demotes it after. This keeps the page idle-state lean - a 100-element grid with permanent force3D would blow mobile memory budgets. - Should I use CSS
will-changeinstead? - If the element animates often (hover state on a button, continuous loop),
will-change: transformon the CSS class is cleaner - the layer stays promoted as long as the user can interact. For one-shot animations, GSAP's auto force3D is leaner because it cleans up. Don't combine both - one is enough. - Why does force3D sometimes cause font blurring?
- GPU-composited layers can interpolate sub-pixel positions, which looks blurry on text. Workaround: snap the element's transform to integer pixels at rest, or use
force3D: falseif the animation is short enough that GPU promotion doesn't help. Modern browsers handle this better than they used to, but it's still a known tradeoff. - What's the difference between force3D: true and force3D: 'auto'?
truekeeps the 3D matrix on the element for the entire tween, even after it ends.'auto'(default) removes it on tween complete. For tight cleanup use 'auto'; for elements that should stay promoted (continuous hover idle, scroll-pinned layers) usetrue.
