Skip to main content
March 23, 2026Dan Rodney/5 min read

GreenSock: ScrollTrigger Media Queries with matchMedia()

Master responsive animations with GreenSock ScrollTrigger

What You'll Master

Media Query Integration

Learn how to implement CSS-like media queries in JavaScript using ScrollTrigger.matchMedia() for responsive animations.

Cross-Device Optimization

Discover techniques to optimize scroll animations for different screen sizes and device types.

Style Contamination Prevention

Understand how to prevent inline CSS contamination when switching between different media query states.

Topics Covered in This JavaScript Tutorial:

Defining Different Animations for Different Screen Sizes, Fixing Inline Style Contamination Across Media Queries

Exercise Preview

preview matchmedia

Exercise Overview

In this exercise, you'll master one of the most crucial skills in modern web animation: creating responsive ScrollTrigger animations that adapt intelligently to different screen sizes. Just as CSS media queries revolutionized responsive design, GSAP's matchMedia() method brings that same adaptive power to your JavaScript animations. You'll learn to craft animations that feel native to each device, whether your users are experiencing your work on a desktop monitor or scrolling through on their mobile device.

Exercise Goal

Transform a single-size scroll animation into a responsive system that adapts seamlessly across desktop and mobile viewports using ScrollTrigger.matchMedia().

Getting Started

  1. For this exercise we'll be working with the GSAP-ScrollTrigger-Multiple folder located in Desktop > Class Files > JavaScript Class. Open that folder in your code editor if it allows you to (like Visual Studio Code does).
  2. In your code editor, open index.html from the GSAP-ScrollTrigger-Multiple folder.
  3. Preview index.html in a browser and test its responsiveness.

    • This is the scrolling animation we created in the previous exercise, optimized for desktop viewing.
    • The animation looks polished when the window is wide, but resize the window to be narrow so the text stacks on top of the photo (and reduce the height to simulate mobile dimensions).
    • Notice how the scrolling animations still function but reveal room for improvement:
      • The text animates too close to the bottom of the viewport—on mobile, we'd prefer it to trigger earlier for better visual hierarchy.
      • The image animation duration feels excessive on smaller screens, leaving users waiting too long to see the final result.
  4. Leave the page open in the browser at this small size—you'll need it for testing after we implement our responsive solution.

These observations highlight a fundamental challenge in responsive animation: what works beautifully on desktop often needs refinement for mobile experiences. Let's solve this with GSAP's powerful matchMedia() method.

Setup Process

1

Open Project Files

Navigate to Desktop > Class Files > JavaScript Class and open the GSAP-ScrollTrigger-Multiple folder in your code editor.

2

Preview Current Animation

Open index.html in a browser to see the existing scrolling animation that works well on wide screens.

3

Test Mobile View

Resize the browser window to simulate mobile size and observe how the animation could be improved for smaller screens.

Current Animation Analysis

Pros
Animations function correctly on mobile devices
Visual effects remain smooth during transitions
Basic responsiveness is maintained
Cons
Text animates too close to the bottom on small screens
Image animation duration is too long for mobile viewing
Timing isn't optimized for mobile user experience

Using ScrollTrigger.matchMedia() to Define Different Animations for Different Screen Sizes

The goal isn't to create entirely different animations—that would fragment your design system. Instead, we'll use the same core animations while fine-tuning timing and trigger points for optimal performance across devices. This approach maintains visual consistency while respecting the unique constraints and opportunities of each screen size.

  1. In the script tag, implement ScrollTrigger.matchMedia() as shown below in bold. This method accepts an object containing your responsive animation definitions:

    <script>
       let sectionImg = document.querySelectorAll('section img');
       let sectionText = document.querySelectorAll('section.text');
    
       ScrollTrigger.matchMedia({});
    
       for(let i=0; i < sectionImg.length; i++) {
  2. Inside matchMedia(), define two breakpoint-specific functions that mirror CSS media query syntax. These will contain your device-optimized animations:

    ScrollTrigger.matchMedia({
       '(min-width: 600px)': function() {
    
       }, 
       '(max-width:599px)':function() {
    
       }
    });
  3. Move your existing animation logic into both functions. Cut the entire for loop and paste it into both functions as shown below. This creates the foundation for device-specific customization:

    <script>
       let sectionImg = document.querySelectorAll('section img');
       let sectionText = document.querySelectorAll('section.text');
    
       ScrollTrigger.matchMedia({
       '(min-width: 600px)': function() {
          for(let i=0; i < sectionImg.length; i++) {

    Code Omitted To Save Space

    };
       }, 
       '(max-width:599px)':function() {
           for(let i=0; i < sectionImg.length; i++) {

    Code Omitted To Save Space

    };
       }
    });
    </script>
  4. Now optimize the mobile experience by adjusting the trigger points in the '(max-width:599px)' function. These modifications account for mobile users' different scrolling patterns and screen real estate:

    '(max-width:599px)':function() {
       for(let i=0; i < sectionImg.length; i++) {

    Code Omitted To Save Space

    gsap.from(sectionImg[i], {
             scrollTrigger:{trigger:sectionImg[i], start:'top 75%', end:'150px  70%', scrub:1, markers:false}, 
             X:movement, opacity:0
          });
          gsap.from(sectionText[i], {
             scrollTrigger:{trigger:sectionText[i], start:'top 75%', end:'bottom 70%', scrub:1, markers:false}, 
             X:-movement, opacity:0
          });
  5. Save your changes and test the mobile optimizations:

    • Ensure your browser window remains narrow and short as previously configured.
    • Reload the page and scroll through the animations.
    • You should observe significant improvements:
      • Text animations now trigger higher in the viewport, creating better visual hierarchy on mobile devices.
      • Image animations complete more quickly (ending 150px from the image top rather than at the image bottom), allowing users to appreciate the final result longer.
  6. Test desktop responsiveness by resizing the window wider—and notice the elements disappear! This reveals a common pitfall in responsive animation.

    The issue stems from how GSAP applies animations through inline CSS. When switching between media queries, the inline styles from one breakpoint persist and contaminate the other. This is a known challenge in responsive animation, but GSAP provides an elegant solution.

Understanding this contamination issue is crucial for professional animation work. Let's implement the fix that ensures clean transitions between breakpoints.

Breakpoint Configuration

FeatureDesktop (600px+)Mobile (599px-)
Image Start Positiontop 75%top 75%
Image End Positionbottom 70%150px 70%
Text Animationbottom 70%bottom 70%
Animation DurationFull scroll heightReduced for faster completion
Recommended: Mobile optimizations provide better user experience with faster image animations and improved timing.
Media Query Syntax

ScrollTrigger.matchMedia() uses standard CSS media query syntax within JavaScript functions, making it familiar for web developers.

Implementation Steps

1

Add matchMedia Structure

Initialize ScrollTrigger.matchMedia() with an empty object to contain your responsive animation logic.

2

Define Breakpoints

Create two functions: one for screens 600px and wider, another for screens 599px and narrower.

3

Duplicate Animation Code

Move your existing for loop into both media query functions to create separate animation contexts.

4

Customize Mobile Settings

Modify the start and end values in the mobile function to optimize animation timing for smaller screens.

Fixing Inline Style Contamination Across Media Queries

ScrollTrigger.saveStyles() is GSAP's purpose-built solution for responsive animation challenges. This method captures the initial inline CSS state for specified elements, creating a clean baseline that ScrollTrigger can restore when switching between media queries. Think of it as creating a snapshot of your elements' original state before any animations modify them. This prevents the style pollution that occurs when animations add inline CSS that persists across breakpoint changes.

  1. Implement the style-saving solution by adding this essential line before your matchMedia() call. This tells ScrollTrigger to monitor and preserve the original styles for both animated element types:

    <script>
       let sectionImg = document.querySelectorAll('section img');
       let sectionText = document.querySelectorAll('section.text');
    
       ScrollTrigger.saveStyles('section img, section.text');
       ScrollTrigger.matchMedia({});
  2. Save your file and test the complete responsive solution:

    • Reload the page and scroll through animations at both wide and narrow window sizes.
    • Resize the window repeatedly to verify smooth transitions between breakpoints.
    • Confirm that animations now look polished and perform consistently across all screen sizes.

    Congratulations! You've successfully implemented professional-grade responsive animations that adapt intelligently to user devices.

    For deeper exploration of advanced matchMedia() techniques and additional responsive animation patterns, consult the GSAP documentation at tinyurl.com/gsap-matchmedia. These skills form the foundation of modern, device-agnostic web animation.

Common Problem Alert

When resizing windows, GSAP's inline CSS from one media query can contaminate another, causing elements to disappear or behave incorrectly.

ScrollTrigger.saveStyles() Solution

Style Recording

Automatically captures initial inline CSS states for specified elements before animations begin. This creates a clean baseline for media query switches.

Contamination Prevention

Ensures that switching between media queries doesn't leave residual inline styles that interfere with new animations.

Final Implementation Checklist

0/3

Key Takeaways

1ScrollTrigger.matchMedia() enables CSS-like media queries for JavaScript animations, allowing different animation behaviors across device sizes
2Responsive animation design requires optimizing timing and positioning specifically for mobile viewports to improve user experience
3The 600px breakpoint effectively separates desktop and mobile experiences for most scroll-triggered animations
4GSAP's inline CSS can contaminate across media queries during window resizing, requiring proactive style management
5ScrollTrigger.saveStyles() prevents style contamination by recording initial CSS states before animations modify elements
6Mobile animations should typically complete faster than desktop versions to account for shorter viewport heights
7Proper responsive animation implementation requires testing across multiple screen sizes and resize scenarios
8Media query functions in ScrollTrigger can contain identical animation logic with different parameter values for optimization

RELATED ARTICLES