useSynchronizedAnimation: Multi-Component Animation Sync
Best Practices Guide for Shared CSS Animations
Introduction
Ensuring that multiple elements across different components animate in perfect sync can be a challenge. The useSynchronizedAnimation hook leverages the Web Animations API to ensure that all animations with the same name stay aligned, regardless of when each element was added to the DOM.
How it works
- Discovery: The hook uses
document.getAnimations()to find all animations matching a specificanimationName. - Tracking: It maintains a global
stashedTimefor each animation name. - Synchronization: When a new component mounts, its animation's
currentTimeis instantly synced to either the already-running instances or the last-knownstashedTime. - Resilience: It handles components mounting and unmounting at different times, ensuring the phase of the animation remains consistent for all visible elements.
Why use useSynchronizedAnimation?
- Visual Polish: Prevents "jarring" effects where identical animations (like spinners or pulsing backgrounds) are out of phase.
- Declarative Interface: Just provide the animation name and a ref, and the hook handles the complex timing logic.
- Low Overhead: Uses the browser's native animation engine rather than manually calculating styles in JavaScript.
See Also
For a detailed technical breakdown and additional implementation patterns, refer to the following resources:
Key Takeaways
- Use descriptive animation names: Avoid generic names like
fadeorrotate. Instead, use specific names likeglobal-pulse-effectto prevent accidental synchronization of unrelated UI elements. - Combine with CSS variables: Use the hook for timing synchronization while using CSS variables for style variations (e.g., different colors for the same synced pulse).
- Check for browser support: While the hook handles support internally, be aware that the Web Animations API is required for synchronization to work.
- Attach the ref correctly: The hook MUST be attached to the specific DOM element that carries the CSS animation name.