Scrolling has become one of the most natural user interactions on the web. Every day, users scroll through countless pages without conscious thought, making scroll-based interactions a powerful yet underutilized tool for creating memorable digital experiences. When implemented thoughtfully, scroll animations can guide users through content, reinforce brand identity, and significantly improve how visitors engage with your site.
Framer Motion, now simply called Motion, provides React developers with an intuitive and powerful toolkit for creating sophisticated scroll animations that feel natural rather than forced. Whether you're building a marketing site, a web application, or an interactive experience, mastering scroll animations elevates your web development projects and creates lasting impressions on visitors.
Understanding Scroll Animations: The Two Fundamental Types
Before diving into implementation, it's essential to understand the two primary categories of scroll animations and how they differ in their relationship to user scrolling behavior.
Scroll-Linked Animations
Scroll-linked animations represent a direct, continuous relationship between the user's scroll position and the visual state of animated elements. In this model, as users scroll through a page, elements update in real-time based on exactly how far they've scrolled. This approach works exceptionally well for effects like progress indicators, parallax scrolling, and any animation where the user should feel direct control over the visual progression.
Key Characteristics:
- Direct synchronization between scroll position and animation state
- Real-time updates as the user scrolls
- User maintains control over animation timing
- Ideal for continuous effects like progress bars, parallax, and scaling effects
Scroll-Triggered Animations
Scroll-triggered animations take a different approach, activating only when specific conditions are met--typically when an element enters or exits the viewport. Rather than continuously following scroll position, these animations wait for a trigger moment before executing. This approach is perfect for reveal effects, fade-ins, slide-in animations, and any scenario where you want to surprise and delight users as they discover new content.
Key Characteristics:
- Discrete activation at specific scroll positions
- Independent playback from scroll action
- Repeatable or one-time execution options
- Ideal for content reveals and attention-grabbing effects
Core Hooks: useScroll and useTransform
At the heart of scroll-based animation in Motion are two essential hooks that work together to track scroll position and convert that information into meaningful animation values.
useScroll Hook
The useScroll hook provides a simple yet powerful interface for tracking scroll position. When you call useScroll(), it returns a scroll progress object containing normalized values between 0 and 1 that represent scroll position. The most commonly used value, scrollYProgress, tracks vertical scroll from the top of the page (0) to the bottom (1), creating a perfect input for animation value mapping.
import { useScroll } from 'framer-motion';
function ScrollProgress() {
const { scrollYProgress } = useScroll();
return <motion.div style={{ scaleX: scrollYProgress }} />;
}
useTransform Hook
The useTransform hook transforms raw scroll values into animation-ready outputs. It maps an input value (like scrollYProgress) through defined ranges to produce outputs for any animatable property.
import { useScroll, useTransform } from 'framer-motion';
function AnimatedElement() {
const { scrollYProgress } = useScroll();
const scale = useTransform(scrollYProgress, [0, 1], [0.5, 1.5]);
const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [0.3, 1, 0.3]);
return <motion.div style={{ scale, opacity }} />;
}
Implementing Scroll-Linked Animations
Scroll-linked animations create direct connections between scroll position and visual changes, providing users with immediate, responsive feedback.
Progress Indicators
One of the most common scroll-linked animations is a scroll progress indicator. Positioned at the top of the viewport, it fills as users scroll through content, providing context about progress and encouraging continued engagement.
Dynamic Scaling Effects
Dynamic scaling effects create visual hierarchies that draw attention to key content. By mapping scroll progress to scale values, you can make headings grow larger as they approach the center of the viewport, creating compelling focal points.
Parallax Effects
Parallax scrolling creates the illusion of depth by moving background and foreground elements at different speeds. Background elements might move at 0.5x scroll speed while foreground elements move at 1.5x, creating genuine perceived depth that adds sophistication to your layouts.
For more on creating depth with scroll-based effects, see our guide to parallax scrolling techniques.
Implementing Scroll-Triggered Animations
Scroll-triggered animations activate when elements enter the viewport, creating opportunities to reveal content and guide attention.
Viewport Detection with whileInView
The simplest approach uses Motion's whileInView prop, which automatically triggers animations when elements enter the viewport:
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }}
>
Content that reveals on scroll
</motion.div>
The viewport configuration provides fine-grained control:
once: Trigger animation only the first timemargin: Adjust when triggering occurs relative to viewport edgesamount: Specify how much of the element must be visible
Fade and Slide Effects
Fade and slide effects work because they feel natural--content gently appearing as users scroll to it mimics how we naturally focus on new information. Combining opacity changes with transforms creates multi-dimensional reveals that feel polished and sophisticated.
Sticky Positioning and Frame Locking
Sticky positioning combined with scroll-triggered animations creates powerful effects where elements lock into place and transform as users scroll past. This technique works well for navigation elements, call-to-action sections, and anywhere you want to maintain attention on specific content.
Best Practices for Performance and User Experience
Creating effective scroll animations requires balancing visual appeal with performance and overall user experience.
Performance Optimization
- Animate only transform and opacity -- These properties are GPU-accelerated
- Use will-change strategically -- Prepare browsers for animations without overuse
- Test on mobile devices -- Animations may perform differently on lower-powered devices
- Avoid layout thrashing -- Keep animations independent of layout calculations
Performance-optimized animations not only feel smoother but also contribute to better SEO performance, as search engines consider page speed and user experience metrics in their rankings.
Accessibility Considerations
- Honor prefers-reduced-motion -- Disable or reduce animations for users who request it
- Ensure keyboard accessibility -- Animated content must remain navigable
- Avoid scrolljacking -- Don't trap users or interfere with expected scrolling
Timing and Pacing
- Keep durations between 300-500ms -- Fast enough to feel responsive, slow enough to be pleasing
- Use ease-out curves -- Work well for reveal animations
- Implement smoothing for scroll-linked effects -- Prevent jittery animations from fast scrolling