obsidian/wiki/concepts/css-animation-js-scroll-conflict.md
2026-05-10 21:26:56 +01:00

1.4 KiB

title source updated tags
CSS animation + JS scrollLeft Conflict — Layout Thrashing daily/2026-05-10.md 2026-05-10
css
animation
javascript
scroll
performance

CSS animation + JS scrollLeft Conflict — Layout Thrashing

Rule

Never write to scrollLeft (or scrollTop) on an element that has an active CSS animation targeting transform or left. The two systems fight over the same rendered position every frame.

What Happens

  • CSS animation runs in the compositor thread, updating transform on every frame
  • JS sets element.scrollLeft = x in the main thread
  • Browser must sync both on each paint → triggers layout thrashing
  • Result: animation "freezes" for a frame, then jumps to catch up; or stutters continuously

This was observed in a GallerySlider component: animation-play-state toggled on hover while scrollLeft was set on arrow-button click. The combination caused a 1-second freeze at animation start.

Fix

Pick one scroll mechanism and remove the other entirely:

Goal Approach
Auto-scroll with buttons Pure JS: requestAnimationFrame loop, no CSS animation
Pure marquee CSS @keyframes translateX, no scrollLeft at all
Gallery (snap) CSS scroll-snap + scrollTo({ behavior: 'smooth' }), no @keyframes