Here is a hard truth about modern web development: You can build the most breathtaking, 3D-layered, cinematic scrolling experience on your M-series Mac, but if it stutters and crashes on a 4G mobile connection, you have failed as a frontend architect.
Over 60% of modern web traffic comes from mobile devices. Yet, developers consistently push heavy, desktop-first JavaScript timelines to mobile browsers, leading to severe layout thrashing, battery drain, and terrible User Experience (UX). If you want to command premium agency pricing, you must master “Graceful Degradation”—the art of scaling back complexity based on the user’s hardware.
If you are serious about performance, you need to know exactly how to manage GSAP responsive animations in Bricks Builder.
By pairing the bare-metal, semantic HTML output of Bricks Builder with the responsive engine of the GreenSock Animation Platform, you can execute logic that adapts flawlessly to any screen. In this expert guide, we will explore the mechanics of GSAP responsive animations Bricks workflows, dissect the fatal flaws of CSS hiding, and teach you how to write JavaScript that natively respects device breakpoints.

The Mobile Motion Crisis: Why Desktop Code Breaks Phones
When a user sits at a 27-inch monitor, they have the screen real estate to process complex visual narratives. Horizontal scrolling, heavy image masking, and intricate stagger animations feel expansive and premium.
On a 6-inch mobile screen, that exact same code feels like a trap. Horizontal pinning on a phone often hijacks the user’s thumb scroll, making them feel like the website is broken. Furthermore, mobile processors (SoCs) have strict thermal limits. Forcing a mobile CPU to calculate deeply nested DOM geometry 60 times a second will cause the device to heat up and the browser to drop frames.
A professional UI/UX workflow dictates that the interaction model must change when the device changes.
The Amateur Mistake: Hiding Elements with CSS Media Queries
When junior developers realize their complex desktop animation looks terrible on mobile, their first instinct is to open the Bricks Builder UI, switch to the mobile breakpoint, and set the animated element to display: none. They then create a simpler version of the element for mobile.
This is a critical architectural error.
CSS display: none only hides the element visually. It does not stop your JavaScript from executing. GSAP is still running in the background, firing ScrollTriggers, calculating math, and updating inline styles on an invisible DOM node. You are burning the user’s mobile battery to animate a ghost.
To manage performance, you must kill the animation at the JavaScript level.
Enter gsap.matchMedia(): The Architect’s Solution
In the past, writing responsive JavaScript meant setting up manual window.addEventListener('resize') functions. It was a nightmare of memory leaks, debouncing, and complex cleanup logic.
Modern GSAP 3 solves this elegantly with gsap.matchMedia().
This feature acts exactly like CSS media queries but for your JavaScript timelines. It allows you to define breakpoints. When the screen size enters a breakpoint, GSAP executes the specific animation. When the screen size exits that breakpoint, GSAP automatically reverts the elements to their original state and kills the event listeners, instantly freeing up the device’s memory.
Step 1: Aligning GSAP with Bricks Builder Breakpoints
To maintain a cohesive system, your JavaScript breakpoints must perfectly match the breakpoints you have set up in the Bricks Builder UI. By default, Bricks uses:
-
Desktop: Base
-
Tablet:
max-width: 991px -
Mobile Landscape:
max-width: 767px -
Mobile Portrait:
max-width: 478px
We will map our GSAP logic to the 991px threshold, creating a distinct “Desktop vs. Mobile/Tablet” environment.
Step 2: Code Architecture for Graceful Degradation
Let’s look at a real-world scenario. You have a portfolio gallery (.portfolio-track). On desktop, you want it to pin and scroll horizontally. On mobile, you want the pinning disabled entirely, allowing the images to stack naturally and simply fade upward as the user scrolls.
Here is how you architect this natively for Bricks Builder using clean BEM classes:
document.addEventListener("DOMContentLoaded", () => {
gsap.registerPlugin(ScrollTrigger);
// 1. Initialize the matchMedia object
let mm = gsap.matchMedia();
// 2. Define the Desktop Breakpoint (Min-width: 992px)
mm.add("(min-width: 992px)", () => {
// Complex Horizontal Pinning for Desktop
const track = document.querySelector(".portfolio-track");
if(track) {
let scrollDistance = track.scrollWidth - window.innerWidth;
gsap.to(track, {
x: -scrollDistance,
ease: "none",
scrollTrigger: {
trigger: ".portfolio-section",
start: "top top",
end: () => "+=" + scrollDistance,
pin: true, // Hijacks scroll for cinematic effect
scrub: 1
}
});
}
// Optional: Return a cleanup function if you use third-party non-GSAP plugins
return () => {
// Custom cleanup code here
};
});
// 3. Define the Mobile Breakpoint (Max-width: 991px)
mm.add("(max-width: 991px)", () => {
// Simple, Battery-Friendly Fade Up for Mobile
const cards = document.querySelectorAll(".portfolio-card");
cards.forEach((card) => {
gsap.from(card, {
y: 50,
opacity: 0,
duration: 0.8,
ease: "power2.out",
scrollTrigger: {
trigger: card,
start: "top 85%", // Fires earlier on mobile
// Notice: No pinning, no heavy scrubbing
}
});
});
});
});The Brilliance of this System: If a user rotates their tablet from portrait (under 991px) to landscape (over 992px), gsap.matchMedia() instantly destroys the fade-up animations, strips the inline styles, and initializes the horizontal pinning. The transition is flawless.
Step 3: Taming the Mobile Viewport (The Address Bar Bug)
When managing responsive GSAP, there is a notorious bug specific to iOS Safari and Chrome for Android.
As a user scrolls down on their phone, the browser’s URL address bar hides to increase screen space. This changes the viewport height (vh). Because ScrollTrigger uses the viewport height to calculate exactly when an animation should start and end, this tiny shift forces GSAP to rapidly recalculate the entire page layout, causing the screen to jump or stutter.
The Fix: You must tell ScrollTrigger to ignore these micro-resizes on mobile. Place this configuration at the very top of your global JavaScript file:
// Ignore UI-related mobile resizes (address bar hiding/showing)
ScrollTrigger.config({ ignoreMobileResize: true });
// Optional: Normalize scroll to prevent iOS overscroll bounce breaking pinned sections
ScrollTrigger.normalizeScroll(true);Real-World Masterclasses: Responsive Motion Done Right
To elevate your design thinking, study how global agencies handle the mobile divide:
-
Apple (Product Pages): Apple defines the standard for 60fps web motion. On a desktop, an iPhone 3D render might rotate wildly based on your scroll position. Open that same page on a physical iPhone, and the heavy 3D WebGL is completely disabled, replaced by highly optimized, static
.webpimages that simply fade in. Apple prioritizes performance over feature parity. -
Cuberto: Known for their heavy use of custom magnetic cursors and liquid hover effects. Because mobile devices do not have “hover” states or mice, Cuberto uses
matchMediato completely strip out their cursor-tracking JavaScript below 768px, falling back to native CSS:activetap states.
Comparative Table: CSS Animation vs. Traditional JS vs. gsap.matchMedia()
| Technical Approach | Implementation | Performance / Memory | UX & Business Impact |
| CSS Media Queries | Hides element via display: none |
🔴 Terrible (JS still runs in background) | Drains mobile battery; causes layout thrashing. |
| Window.Resize JS | Manual if/else logic on window width |
🟡 Moderate (Requires heavy manual garbage collection) | High risk of memory leaks and duplicated triggers. |
gsap.matchMedia() |
Native GSAP breakpoint context | 🟢 Flawless (Auto-reverts and cleans memory) | Premium UX: Guarantees 60fps, responsive interactions. |
FAQ: Troubleshooting Responsive GSAP in Bricks
Q1: Why is my animation playing twice or looking glitched when I resize the browser window? A: If you are not using gsap.matchMedia(), or if you forgot to put your timelines inside the mm.add() function, GSAP is stacking new animations on top of old ones every time the window resizes. matchMedia automatically calls a revert() function to strip the old math away before applying the new math. Ensure your scope is strictly inside the breakpoint block.
Q2: Does matchMedia work if I am using Bricks Builder’s native AJAX page transitions (PJAX)? A: Yes, but it requires architecture. When Bricks loads a new page via AJAX, the browser does not refresh, meaning your matchMedia contexts remain active in memory. You must assign your matchMedia to a variable (e.g., let mm = gsap.matchMedia();), listen for the bricks/ajax/success event, and run mm.revert(); to clear the old page’s breakpoints before the new page initializes.
Q3: How do I handle responsive SVG Morphing? A: SVG viewBoxes behave differently than standard HTML divs. If you are morphing an SVG that changes size drastically between desktop and mobile, standard responsive CSS might distort the vector path. It is often safer to use matchMedia to swap out two entirely different SVGs (hiding one and showing the other) and running separate MorphSVG logic for each, rather than forcing one complex path to scale infinitely.
Conclusion & The Architect’s Next Steps
Understanding how to manage GSAP responsive animations in Bricks Builder is the dividing line between building websites that look good in a portfolio and engineering platforms that perform in the real world.
By strictly managing your JavaScript execution with gsap.matchMedia(), prioritizing GPU-accelerated properties, and fully utilizing the clean, bare-metal DOM that Bricks Builder provides, you eliminate mobile layout thrashing entirely. You are no longer just coding; you are architecting a fluid, device-aware digital experience.
Stop hiding broken animations with CSS. Take absolute control of your logic.
Your next practical step: Open your current Bricks project. Identify your heaviest ScrollTrigger section. Wrap that code in a gsap.matchMedia("(min-width: 992px)") block, and write a radically simplified fallback for mobile. Deploy it to staging, open it on a physical smartphone, and feel the immediate difference in rendering speed.

