Topics Covered in This JavaScript Tutorial:
Defining Different Animations for Different Screen Sizes, Fixing Inline Style Contamination Across Media Queries
Exercise Preview

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.
Transform a single-size scroll animation into a responsive system that adapts seamlessly across desktop and mobile viewports using ScrollTrigger.matchMedia().
Getting Started
- 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).
- In your code editor, open index.html from the GSAP-ScrollTrigger-Multiple folder.
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.
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
Open Project Files
Navigate to Desktop > Class Files > JavaScript Class and open the GSAP-ScrollTrigger-Multiple folder in your code editor.
Preview Current Animation
Open index.html in a browser to see the existing scrolling animation that works well on wide screens.
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
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.
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++) {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() { } });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>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 });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.
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
| Feature | Desktop (600px+) | Mobile (599px-) |
|---|---|---|
| Image Start Position | top 75% | top 75% |
| Image End Position | bottom 70% | 150px 70% |
| Text Animation | bottom 70% | bottom 70% |
| Animation Duration | Full scroll height | Reduced for faster completion |
ScrollTrigger.matchMedia() uses standard CSS media query syntax within JavaScript functions, making it familiar for web developers.
Implementation Steps
Add matchMedia Structure
Initialize ScrollTrigger.matchMedia() with an empty object to contain your responsive animation logic.
Define Breakpoints
Create two functions: one for screens 600px and wider, another for screens 599px and narrower.
Duplicate Animation Code
Move your existing for loop into both media query functions to create separate animation contexts.
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.
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({});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.
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
Specify the exact elements being animated to prevent style contamination
Resize browser window multiple times to ensure smooth transitions
Confirm that both desktop and mobile animations perform optimally