P
Pixel Show
CSSAnimation

CSS Animations vs JavaScript Animations: Which to Use

When CSS animations perform better, when you need JavaScript, and how to combine both for smooth web animations.

The Performance Divide

CSS animations run on the compositor thread — separate from the main thread where JavaScript executes. This means CSS animations can stay smooth at 60fps even when JavaScript is busy.

But not all CSS animations get this benefit. Only transform and opacity are composited. Animating width, height, top, or background-color triggers layout or paint — just as slow as JavaScript.

When CSS Animations Win

  • Simple transitions (hover effects, fades, slides)
  • Looping animations (spinners, pulsing indicators)
  • Scroll-driven animations (CSS-only with animation-timeline)
  • Any animation that only uses transform and opacity
The syntax is simple and no JavaScript needed:
.card {
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.card:hover {
  transform: translateY(-4px);
  opacity: 0.95;
}

When JavaScript Animations Win

  • Complex sequenced animations (step 1, then 2, then 3)
  • Physics-based animations (spring, bounce with momentum)
  • Animations that respond to user input in real-time (drag, gesture)
  • Dynamically calculated values (animate to a computed position)
Libraries like Framer Motion and GSAP handle these cases well.

The Web Animations API

A middle ground: the Web Animations API gives JavaScript control over animations that run on the compositor thread. You get the performance of CSS with the flexibility of JavaScript.

element.animate(
  [{ transform: 'translateX(0)' }, { transform: 'translateX(200px)' }],
  { duration: 500, easing: 'ease-out' }
)

View Transitions

The View Transitions API handles page-level animations. When navigating between pages or states, elements animate smoothly between their old and new positions. Think of it as automatic morphing transitions.

Performance Rules

  • Animate transform and opacity only when possible
  • Use will-change sparingly — it reserves GPU memory
  • Avoid animating during page load
  • Test on low-end devices — your MacBook Pro is not representative
  • Reduce motion for users who prefer it: prefers-reduced-motion media query

Practical Advice

Start with CSS transitions for hover and state changes. Add CSS keyframe animations for loading states and loops. Reach for JavaScript animation libraries only when CSS cannot express what you need. This covers 90% of web animation needs.

Build websites faster

Staxl — premium templates for modern web projects

Explore Staxl →