function updateHeaderHeight() {
        // Get the height of #brx-header
        const headerHeight = document.querySelector('#brx-header').offsetHeight;
          
        // Store the height in the CSS custom property --header-height
        document.documentElement.style.setProperty('--brxw-header-height', headerHeight + 'px');
    }

    // Execute the function as soon as the document is ready
    document.addEventListener('DOMContentLoaded', function() {
        updateHeaderHeight();  // Initial update of header height when the document is ready

        // Update the header height on window resize and orientation change
        window.addEventListener('resize', updateHeaderHeight);
        window.addEventListener('orientationchange', updateHeaderHeight);
});

Advanced Bricks Builder Tips for Smooth Frontend Animation

To trigger GSAP animations on scroll using ScrollTrigger, load GSAP + the ScrollTrigger plugin, register it with gsap.registerPlugin(ScrollTrigger), then attach a scrollTrigger config (with trigger, start, end, and optionally scrub or pin) to any gsap.to(), gsap.from(), or timeline. ScrollTrigger converts scroll position into animation progress — no scroll-event listeners, no manual math. On WordPress, you enqueue the two scripts and drop the same JS into a Bricks Builder Code element.

Why Bricks Builder Pairs So Well With GSAP

Unlike heavier legacy page builders that wrap every element in nested div soup, Bricks Builder outputs lean, semantic HTML. That matters more than most people realize: GSAP’s ScrollTrigger plugin measures your page by calculating exact pixel positions on load. The cleaner your markup, the more predictable those calculations are.

That said, clean markup alone won’t save you from the four issues below — those come from how and when the browser renders content, not just what the HTML looks like.

Issue #1: Flash of Unstyled Content (FOUC) Before Animations Load

The Symptom

For a split second on page load, your content is fully visible in its final position. Then it snaps down to its “start” state and begins the animation you actually wanted the visitor to see.

The Fix

Many beginners set opacity: 0 directly inside the Bricks Builder UI. This is a common mistake — it can create accessibility issues for screen readers and often conflicts with GSAP’s own animation engine.

Instead, create a global utility class in Bricks (for example .gsap-reveal) and add it to your Global CSS:

/* Hide elements safely before JS takes over */
.gsap-reveal {
  visibility: hidden;
}

Then animate with autoAlpha instead of opacity:

gsap.to(".gsap-reveal", {
  y: 0,
  autoAlpha: 1, // switches visibility to 'inherit' AND fades opacity in one property
  duration: 1.2,
  ease: "power3.out"
});

This keeps elements invisible but still occupying layout space until GSAP is ready to take over — no flash, no layout shift.

Issue #2: Incorrect ScrollTrigger Start and End Points

The Symptom

You set start: "top 80%", but the animation fires way too early or too late compared to what you expected.

The Fix

This almost always comes down to lazy-loaded images. WordPress and Bricks Builder both lazy-load images by default. When GSAP measures the page on load, an unloaded image might report a height of 0px. Once it finishes loading, the page shifts — but GSAP doesn’t automatically know that happened.

Two ways to solve it:

  1. Set explicit width/height or aspect ratios on every Image element in the Bricks Builder UI. This reserves the correct space in the layout before the image even downloads.
  2. Force a recalculation after everything has finished loading:
window.addEventListener("load", () => {
  // Redraws all ScrollTrigger lines after fonts and images finish rendering
  ScrollTrigger.refresh();
});

Issue #3: Jumpy or Stuttering Animation on Mobile Browsers

The Symptom

The animation runs perfectly on desktop, but on an iPhone or Android browser it stutters and recalculates constantly while scrolling.

The Fix

Mobile browsers hide and show the address bar as you scroll, which continuously changes the viewport height (vh). Since ScrollTrigger reacts to viewport size changes, this can trigger unnecessary recalculations on every scroll tick.

Add this configuration once, at the very top of your script, before any ScrollTrigger instances are created:

// Prevent unnecessary recalculations from mobile address bar resizing
ScrollTrigger.config({ ignoreMobileResize: true });

// Optional: smooth out iOS overscroll bounce on pinned sections
ScrollTrigger.normalizeScroll(true);

Issue #4: Pinning Creates Unwanted Whitespace

The Symptom

You use pin: true to lock a background element in place while content scrolls over it, but GSAP inserts a “pin-spacer” wrapper that pushes your layout down, breaking your Bricks structure.

The Fix

Disable automatic pin spacing and manage the layering manually:

let ctx = gsap.context(() => {
  const bgLayer = document.querySelector(".fixed-transparent-bg");
  const scrollSection = document.querySelector(".foreground-scroll-section");

  if (bgLayer && scrollSection) {
    ScrollTrigger.create({
      trigger: scrollSection,
      start: "top top",
      end: "bottom bottom",
      pin: bgLayer,
      pinSpacing: false, // stops GSAP from adding extra padding
      scrub: true
    });
  }
});

Wrapping your code in gsap.context() also makes cleanup much easier — especially important if your site uses Bricks Builder’s AJAX page transitions (see FAQ below).

Quick Reference: Common Fixes at a Glance

Issue Beginner Mistake Better Approach Why It Matters
FOUC / Flicker opacity: 0 in Bricks UI visibility: hidden in CSS + autoAlpha in GSAP Prevents accessibility issues and layout flashes
Broken Triggers Manual pixel offsets (+=500px) Explicit image dimensions + ScrollTrigger.refresh() Scales correctly across devices
Mobile Stutter Turning animation off on mobile ScrollTrigger.config({ ignoreMobileResize: true }) Keeps animation consistent everywhere
Pinning Whitespace Negative CSS margins pinSpacing: false Preserves clean Bricks Builder structure

Real-World Examples Worth Studying

Looking at how established sites handle Web Animation can clarify best practices:

  • Luxury e-commerce sites typically lock in strict aspect ratios on product grids so scroll-triggered reveals never miscalculate, regardless of connection speed.
  • Apple’s product pages rely heavily on ScrollTrigger.normalizeScroll() for their scrubbed 3D hardware showcases, smoothing out trackpad inertia so animations don’t overshoot.

FAQ

Q1: Why does my GSAP animation break after Bricks Builder’s AJAX page transitions? A: AJAX navigation doesn’t perform a hard page refresh, so old ScrollTrigger instances stay active in memory and conflict with the new page’s DOM. Wrap your GSAP code in gsap.context(), listen for the Bricks AJAX transition event, and call ctx.revert() to clean up old animations before the new page renders.

Q2: How do I read overlapping ScrollTrigger markers during development? A: Instead of the default markers: true, customize marker styling directly in your ScrollTrigger config, for example setting distinct colors and an indent value to visually separate overlapping trigger lines.

Q3: Why does scrub: true feel jittery on Windows machines with a standard mouse? A: Trackpads send smooth, continuous scroll data, while standard mouse wheels send “stepped” data. Changing scrub: true to a numeric value like scrub: 1 adds a short easing delay that smooths out the choppy input into a fluid glide.

Final Takeaway

Most GSAP and ScrollTrigger problems in Bricks Builder come down to timing — the browser changing the page after GSAP already did its math. Once you build the habit of reserving space for lazy-loaded content, refreshing ScrollTrigger after full load, and configuring mobile behavior up front, you’ll spend far less time debugging and far more time refining the animation itself.