Jump to content
Search Community

Flickering and Fast-Scrolling Issues with GSAP ScrollTrigger on Safari for Footer Reveal Animation

mrriyadh
Moderator Tag

Recommended Posts

Posted

I’m working on a Next.js project with GSAP free version, where I’ve implemented a footer reveal animation inspired by the behavior on the Raxo website. The goal is to make the footer overlap the main content when a specific section (<div ref={titleRef}>) becomes visible at the bottom of the viewport.

Here’s a brief description of my setup:

  • The main content is pinned while scrolling.
  • The footer slides up and overlaps the main content as the user scrolls to the end.
  • I’m using GSAP ScrollTrigger for the animations and react for component structure.

You can find my implementation on CodeSandbox:
👉 CodeSandbox Link


 

Problems:

  1. Pinning Issue: The main content pinning is not smooth, especially during the transition when the footer starts overlapping the main content. The transition feels jittery and unstable.

  2. Footer Flickering: The footer flickers significantly on Safari during the reveal animation. While the flickering in Chrome is minimal and tolerable, it’s highly noticeable and disruptive on Safari (both macOS and iOS).

  3. White Area Beneath Footer on Fast Scrolling: During fast scrolling, the pinned footer (set to 100vh) moves slightly, and a white area becomes visible beneath the footer. It seems like the footer isn’t fully pinned to the bottom during these fast scroll events.

     

    Relevant Code:

    Here’s the simplified code structure. The complete implementation is available in the CodeSandbox Link:

    CustomLayout.js

    "use client"; import { useEffect, useRef } from "react"; import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); export default function CustomLayout({ children }) { const titleRef = useRef(null); const containerRef = useRef(null); const mainContentRef = useRef(null); useEffect(() => { if (!titleRef.current || !containerRef.current || !mainContentRef.current) return; const title = titleRef.current; const container = containerRef.current; const mainContent = mainContentRef.current; gsap.set(container, { y: "100%", force3D: true, backfaceVisibility: "hidden" }); gsap.set(mainContent, { opacity: 1, scale: 1, force3D: true, backfaceVisibility: "hidden" }); const timeline = gsap.timeline() .to(mainContent, { opacity: 1, scale: 0.99, duration: 1, ease: "power3.out", }) .to(mainContent, { y: "-2%", duration: 0.5, ease: "power2.inOut", }); ScrollTrigger.create({ trigger: title, start: "bottom bottom", end: () => `+=${container.getBoundingClientRect().height}`, pin: mainContent, animation: timeline, pinSpacing: false, scrub: 1, onEnter: () => { gsap.to(container, { y: 0, duration: 1, ease: "power4.out", clearProps: "transform", }); }, onLeaveBack: () => { gsap.to(container, { y: "100%", duration: 1, ease: "power4.out", clearProps: "transform", }); }, }); ScrollTrigger.refresh(); return () => { ScrollTrigger.killAll(); }; }, []); return ( <div className="flex flex-col"> <header>Header Content</header> <main ref={mainContentRef} className="flex-grow bg-gray-100"> {children} <div ref={titleRef} className="h-[1px] opacity-0 bg-transparent flex items-center"> <p className="relative lg:absolute h-0 w-full bg-red-500 text-5xl font-bold text-white text-center"> Footer Title </p> </div> </main> <footer style={{ minHeight: "100vh", transform: "translateZ(0)", willChange: "transform", }} ref={containerRef} className="lg:relative bg-black text-white h-[calc(100vh+180px)] sm:h-auto z-[2] overflow-hidden" > Footer Content </footer> </div> ); }
     

    What I've Tried:

Using force3D and backfaceVisibility:

 

         Added force3D: true and backfaceVisibility: hidden to both the footer and main content, but these didn’t resolve the flickering, pinning                      smoothness, or the white area issue.

  1. Tuning ScrollTrigger Configurations:

    • Adjusted the start, end, and pinSpacing values for ScrollTrigger.
    • Experimented with invalidateOnRefresh, fastScrollEnd, and easing functions without success.
  2. Testing with or Without Hardware Acceleration in CSS:

    • Tried enabling/disabling transform: translateZ(0) and will-change: transform, but the flickering and white area issues persist.
  3. Adjusting Duration and Scrub:

    • Changed the animation duration and scrub values in GSAP. This slightly improved the pinning but didn’t eliminate the white gap during fast scrolls.

 

Environment:

  1. Browser: Major problem in Safari (macOS and iOS).
  2. GSAP Version: Free version ([email protected]).
  3. React: [email protected].
  4. Framework: Next.js.

Expected Behavior:

  1. The main content should pin smoothly during scrolling, and the footer should reveal without any flickering or jittering.

 


Questions:

  1. Is the flickering in Safari a known issue, and are there any workarounds or best practices for smooth pinning and reveal animations?
  2. Why does fast scrolling cause the footer to shift, revealing the white area beneath it, and how can I prevent this behavior?
  3. Are there specific optimizations in GSAP ScrollTrigger to handle such issues on Safari?

Any help or suggestions to fix these issues would be greatly appreciated!


References:

  1. Similar footer behavior: https://raxo.co/

During fast scrolling, the footer should maintain its position without revealing any white area beneath it.

Posted

Hi there!

 

Your CodeSandbox link isn't available. It says: 

Quote

Unable to access this workspace
It is likely that you are not a member of the team that this project belongs to. To be able to access the web editor of this repository and edit the code, you need to be invited to the team.

 

I see you're using React -

Proper cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE.

 

Since GSAP 3.12, we have the useGSAP() hook (the NPM package is here) that simplifies creating and cleaning up animations in React (including Next, Remix, etc). It's a drop-in replacement for useEffect()/useLayoutEffect(). All the GSAP-related objects (animations, ScrollTriggers, etc.) created while the function executes get collected and then reverted when the hook gets torn down.

 

Here is how it works:

const container = useRef(); // the root level element of your component (for scoping selector text which is optional)

useGSAP(() => {
  // gsap code here...
}, { dependencies: [endX], scope: container }); // config object offers maximum flexibility

Or if you prefer, you can use the same method signature as useEffect():

useGSAP(() => {
  // gsap code here...
}, [endX]); // simple dependency Array setup like useEffect()

This pattern follows React's best practices.

 

We strongly recommend reading the React guide we've put together at https://gsap.com/resources/React/

 

If you still need help, here's a React starter template that you can fork to create a minimal demo illustrating whatever issue you're running into. Post a link to your fork back here and we'd be happy to take a peek and answer any GSAP-related questions you have. Just use simple colored <div> elements in your demo; no need to recreate your whole project with client artwork, etc. The simpler the better. 

Posted

I am facing the flickering and content jumping issue in Safari not in Chrome when scrolling.
What should I do??
Should I buy the paid version gsap?

Posted

That demo is not working neither, it seems that there is an issue while connecting to the repo.

 

As we understand that creating a minimal demo from an existing repo is fast and simpler we can't fork that repo and test any  changes we make to the code, so please just fork one of the demos in our Next collection or start from a new NextJS project in Stackblitz.

 

https://stackblitz.com/@GSAP-dev/collections/gsap-nextjs-starters

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...