Why `transition: all` Is Problematic in CSS: Performance & Best Practices
transition: all forces the browser to animate every changeable property on an element, causing unintended GPU-offloaded animations, expensive layout recalculations, and poor animation interruptibility.
The emilkowalski/skills repository explicitly flags transition: all as an anti-pattern in modern CSS animation workflows. According to the source code analysis in review-animations/SKILL.md and improve-animations/AUDIT.md, this shorthand introduces significant performance bottlenecks and architectural constraints that can degrade user experience.
The Problem with transition: all
When you declare transition: all 250ms ease, you instruct the browser to watch and interpolate every animatable property on that element. While this appears convenient for rapid prototyping, it creates a contract where properties like width, height, margin, box-shadow, and color all trigger animation frames simultaneously.
Performance and Architectural Issues
Unintended Property Animations
The browser may attempt to animate properties that were never designed for smooth interpolation or GPU acceleration. As noted in review-animations/SKILL.md at line 47, "transition: all animates unintended properties off-GPU," forcing expensive paint operations on the CPU. The audit file at improve-animations/AUDIT.md line 74 further emphasizes that this unbounded property animation can trigger jank when properties like box-shadow or border-color change unexpectedly.
Loss of Control Over Timing and Easing
Different properties require distinct animation characteristics. A transform might need a bouncy cubic-bezier, while opacity works best with linear interpolation. Using transition: all shackles every property to a single timing function and duration, making some animations feel sluggish while others appear too aggressive.
Reduced Interruptibility and Animation Retargeting
CSS transitions can be retargeted mid-animation from their current state, whereas keyframe animations restart from zero. The repository highlights this critical distinction at improve-animations/AUDIT.md line 62: "keyframes restart from zero" while "transitions retarget from the current state." When transition: all triggers on rapidly toggled elements, the animation state resets perceptibly, causing visual jumps that break perceived performance.
Layout and Paint Overhead
Animating layout-affecting properties—width, height, padding, margin, top, or left—forces the browser to recalculate layout on every frame. Because transition: all includes these properties by default, it can trigger expensive layout-and-paint cycles. The audit at improve-animations/AUDIT.md lines 73-75 specifically warns against animating layout properties and identifies transition: all as a common vector for these performance regressions.
Accessibility and Reduced Motion Concerns
Broad transition declarations make it difficult to implement granular prefers-reduced-motion fallbacks. When all properties animate together, you cannot easily preserve simple opacity fades while disabling costly transform animations for users with vestibular disorders.
Best Practices for CSS Transitions
Replace the catch-all approach with explicit, GPU-friendly property targeting.
The Anti-Pattern: Using transition: all
.button {
background: #0066ff;
color: #fff;
padding: 12px 24px;
border-radius: 4px;
transition: all 250ms ease; /* animates every property */
}
.button:hover {
background: #0055dd;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
Why this fails: Hovering triggers transitions on background, box-shadow, and potentially border-radius—many of which require CPU-based painting and cannot be composited on the GPU.
Targeting GPU-Accelerated Properties
.button {
background: #0066ff;
color: #fff;
padding: 12px 24px;
border-radius: 4px;
/* Only animate compositor-friendly properties */
transition: transform 200ms ease, opacity 200ms ease;
}
.button:hover {
transform: scale(1.05);
opacity: 0.95;
}
Benefits:
transformandopacityrun exclusively on the compositor thread, avoiding layout and paint work- Independent timing control allows
transformto useease-outwhileopacityuseslinear - Explicit property lists prevent accidental animation of expensive layout properties
Handling Reduced Motion Preferences
@media (prefers-reduced-motion: reduce) {
.button {
transition: none; /* disable non-essential motion */
}
}
This approach respects user accessibility settings while maintaining the performance benefits of targeted transitions for users without motion preferences.
Summary
transition: allanimates unintended properties including expensive, non-GPU-accelerated values likebox-shadowandcolor, as flagged inreview-animations/SKILL.md.- Layout properties trigger recalculation when included in
all, causing jank on every frame according toimprove-animations/AUDIT.md. - Animation retargeting fails with keyframe-based transitions, causing visual jumps when elements toggle rapidly.
- Explicit property targeting using only
transformandopacitykeeps animations on the compositor and allows per-property easing control. - Accessibility requires granularity that
transition: allcannot provide; explicit properties enable betterprefers-reduced-motionsupport.
Frequently Asked Questions
What properties should I animate instead of using transition: all?
Animate only transform and opacity whenever possible. These properties bypass the layout and paint phases, running entirely on the GPU's compositor thread. According to the emilkowalski/skills audit files, this approach eliminates the "unbounded property animation" risk while maintaining 60fps performance on mobile devices.
Does transition: all affect page performance on modern browsers?
Yes. Even modern browsers cannot optimize transition: all because they must monitor every animatable property for changes. When layout-affecting properties like width or margin change, the browser performs expensive layout recalculations on every animation frame, as documented in improve-animations/AUDIT.md.
How do I disable animations for users who prefer reduced motion?
Use the prefers-reduced-motion media query to set transition: none or reduce transition durations to nearly zero. When you avoid transition: all, you can selectively disable heavy transforms while keeping subtle opacity changes that don't trigger vestibular disorders.
Can transition: all cause layout shifts?
Absolutely. Because transition: all includes layout properties like height, width, padding, and margin, any change to these values triggers a layout pass that can shift surrounding elements. The repository specifically warns against animating layout properties in improve-animations/AUDIT.md, noting that these shifts cause cumulative layout shift (CLS) penalties and visual instability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →