I had some free time last week. Not uncommon when a project starts; images and copy start slow but become an avalanche later on. So while I had time to fill, I took some inspiration from a Webflow legend, Timothy Ricks, and built a small animations library. It took me four and a half hours, with some AI help on the tougher bits.

If you're anything like me and enjoy building in Webflow but crave those slick GSAP animations, you've probably gone down the rabbit hole a few times. It's especially fun now that Webflow and GSAP are best mates since the acquisition, and GSAP is free for everyone.

Once a site is built I tend to handle animations and interactions at the end, and I often need to quickly drop in common patterns: classic fade-ins, slide-ups, reveals, staggered lists, and those lovely SplitText reveals for headlines (tip of the hat to Timothy Ricks for the inspiration). These are time-consuming to recreate in Webflow interactions, unwieldy to load, and not easily portable between projects. Setting them up one by one is repetitive, especially when you're keeping things consistent across a site. And don't get me started on the annoying flash on hero elements before the animation kicks in.

So I built a little helper script: an attribute-driven system that adds these animations just by tagging elements in Webflow.

What it does

  • Easy element animations. Slap an attribute like k-zoom-in or k-anim="rise-up" on an element and it animates on scroll, or on load.
  • Staggered groups. Add k-stagger-group to a parent and its tagged children animate in sequence. Nice for lists and cards.
  • Text animations. The classic SplitText effects, updated for GSAP's newest SplitText. words-slide-up or letters-fade-in-random on a heading does its magic. I had AI help mapping the animation trees so element animations and text-split animations never clash; I was stumped on that point, and LLMs are very, very good at coding.
  • Above-the-fold handling. data-k-loadanim="true" fires the animation immediately on load.
  • FOUC prevention. A simple .k-hideonload class hides elements initially but keeps them visible in the Webflow Designer (a nifty trick with html.wf-design-mode), and the script smoothly takes over.
  • Basic controls. Tweak with data-anim-duration, data-scroll-start, data-anim-replay and data-anim-delay.
  • Plays nice (hopefully). It checks GSAP is loaded and tries not to break anything if it isn't.

Why bother, if Webflow is integrating GSAP natively?

Yeah, I know. My timing is a little off, with Webflow integrating GSAP into the interactions interface. Time wasted? Maybe. But Webflow interactions are often class-based, which means combo classes or wrapper elements, all management and mental overhead. I see this script as a companion: a pre-defined set of my favourite animations ready to go with a few attributes. If I want a rise-up effect, I know exactly what to add.

Quick look at how to use it

It boils down to some CSS in your site's head and the main script in your footer. The head CSS hides .k-hideonload elements while keeping them visible in the Designer. Then you tag your elements:

<!-- above the fold / on load -->
<div k-zoom-in class="k-hideonload" data-k-loadanim="true">I animate immediately!</div>
<h1 words-slide-up class="k-hideonload" data-k-loadanim="true">Split text on load</h1>

<!-- scroll-triggered, further down -->
<div k-fade-in data-scroll-start="top 80%">I fade in at 80% from the top.</div>
<p letters-fade-in>These letters fade in on scroll.</p>

There are more attributes for duration, delay and replay, because GSAP really is a full-on animation beast and I'm barely scratching the surface. The 80/20 rule is in full effect.

Want to try it or see the code?

The script (V2.2 now) and a detailed how-to guide live in my snippet library. Feel free to grab it, pick it apart, or tell me if you find it useful. It's only 16kb, under 9kb minified, so it loads with negligible delay.

It's been a fun little project that filled some spare time, and, as always with code, it's probably a perpetual work in progress. But for now, it's doing the job for me.

Cheers,

Mark