You can get a perfectly clean GSAP page-load animation in Webflow — no flash, no jump — with a small, reusable pattern you drop into any project. Webflow now ships automatic FOUC handling for GSAP interactions, and it covers a lot of cases. But on heavier pages and more complex layouts you can still catch a flicker on that very first load, and this is how you take full control of it.
The trick isn’t a hack. It’s understanding one small timing gap between when the browser paints the page and when GSAP applies the initial states of your animation — and closing it with three lines of CSS plus a single GSAP action. Once you see why it happens, you’ll reach for the same fix every time.
How it works
When GSAP drives a page-load animation, it needs a brief moment after the page starts rendering to apply the initial conditions — the starting opacity, position, or transform each element animates from. Until that moment arrives, the browser has nothing to go on but your normal Webflow styles, so it paints the elements in their final state. Then GSAP kicks in, snaps them to the animation’s starting point, and plays. That snap — final state, then suddenly the start state — is the flicker. The heavier the page, the longer the browser takes to get to GSAP, and the more obvious the flash becomes.
So the fix is to hide things until GSAP is ready. The instinct is to hide every animated element, but that gets messy fast. Instead, hide the innermost wrapper that contains all of them: wide enough to cover everything in the animation, narrow enough that you’re not blacking out unrelated parts of the page. Set that wrapper’s opacity to 0 and nothing inside it can flash.
Where you put that CSS matters. Not in the Designer — the wrapper would be invisible while you work. Not inside the GSAP interaction — GSAP still needs its moment, so you’d just move the flicker onto the wrapper. It goes in the page’s <head>, which the browser reads and applies before it paints the content. By the time anything appears on screen, the wrapper is already at opacity 0.
The last piece is safety. Your CSS hides the wrapper, but something has to reveal it — and that something is GSAP, which knows exactly when the animation is ready. If a visitor has JavaScript disabled, GSAP never runs, so you must make sure the hide rule never runs either. Otherwise the content stays invisible forever. Webflow gives you a clean hook for that: the w-mod-js class.
How to use it
-
Find the wrapper(s) to hide. Pick the innermost container(s) that hold every animated element. In the demo the animated elements live in two places — the navbar and the hero — so instead of hiding the whole page wrapper, we target two: the nav wrapper and the video section.
-
Tag them with a custom attribute. Rather than juggle class and combo-class selectors, give each wrapper the same custom attribute — name it
remove-flicker(no value needed). Apply it to the first element, then copy-paste it onto the others. -
Hide them from the
<head>. In Page Settings → Inside<head>tag, add a style block that targets the attribute and scopes it to JavaScript being active:<style> .w-mod-js [remove-flicker] { opacity: 0; } </style>[remove-flicker]matches every element carrying the attribute, whatever its classes. The.w-mod-jsprefix — a class Webflow adds to<html>only when JS is running — means the rule applies only when GSAP will actually bring the elements back. -
Reveal them with GSAP. Open your page-load interaction and add a new action (call it remove flicker). Set the target type to Attribute and the attribute name to
remove-flicker. Then make it instant: duration0, start0, type to, property opacity, value 100%. No easing, no delay — the wrappers flip from invisible to visible the instant GSAP says go. -
Publish and test on the live link. The flicker only shows on the published site, so check there — refresh a few times and open it in a new tab. The navbar and headings should now load clean every time.