Webflow’s GSAP interaction settings — repeat, runs on, and conditional playback — are the difference between an animation that merely works and one that loops cleanly, performs well at scale, and treats every visitor with respect. This lesson works through four looping patterns (a marquee, cascading text, a scroll-triggered button, a hover stagger) and then the two settings that quietly matter most for real sites.
The star of the show is a distinction that trips up almost everyone: repeat exists in two places — on the interaction and on each action — and they don’t mean the same thing.
How it works
Interaction repeat vs action repeat. Interaction-level repeat loops the entire timeline — every action together — as one group. Action-level repeat loops a single action independently. For a marquee that’s one action moving a strip from 0% to -100% on X, the two are equivalent: repeat the action forever or repeat the interaction forever, you get the same endless scroll. But the moment a timeline has several actions, they diverge sharply. A cascading text loop with four actions (text-out, text-in, arrow-out, arrow-in) must loop as a group — that’s interaction repeat. Apply infinite to each action instead and they desync into chaos: the text resets while the arrow is mid-flight.
Action repeat + back and forth is where you get surgical. “Back and forth” plays an action forward, then in reverse, on each cycle. Combined with a repeat count, you can compose exact patterns. In the scroll example, the button’s letters should exit and re-enter twice then settle, while the circle behind them pulses forever. The letters’ action uses repeat 3 with back-and-forth (out-in-out-in-out-in → ends settled), and the circle’s action uses infinite + back-and-forth (expand-contract forever). Only action-level repeat can loop one part while another stops — interaction repeat would loop everything.
Runs on decides which pages load an interaction. By default it’s the page where you built it, and that’s deliberate: set it to “all pages” and Webflow ships that JavaScript to every page — parsing it, evaluating it, checking for a target that may not exist — even where it’s irrelevant. On a 30- or 50-page site that adds up. Scoping “runs on” to the pages that need the interaction is a real, free performance optimization.
Conditional playback is the accessibility and responsiveness lever, and it does two things. First, it reads the browser’s prefers-reduced-motion feature — the OS-level “reduce motion” setting people with vestibular disorders or motion sensitivity turn on — and lets you disable the interaction or skip it to the end for those users. Parallax, fast movement, scaling, and looping can genuinely cause discomfort, so honoring this isn’t a nice-to-have. Second, it lets you choose which breakpoints an interaction runs on, so a heavy desktop effect can simply not run on mobile, where it might be overwhelming or tax a low-powered device.
How to use it
-
Marquee (interaction repeat). Put two identical content groups side by side in a flex wrapper with
overflow: hidden; set the flex children to don’t shrink or grow. Animate the group’s X from0%to-100%, linear easing, then set repeat: infinite on the interaction (or the single action — equivalent here). -
Cascading text (interaction repeat). Build the sequence as separate actions (text-out, text-in, arrow-out, arrow-in), using from to on the “in” actions with a flipped-sign “from” so elements fall in from above rather than reversing. Set repeat: infinite on the interaction so all four loop together, in sync.
-
Scroll button (action repeat). Trigger on scroll with trigger actions (not scrub-on-scroll) when the button hits mid-viewport. Give the letters’ action repeat: 3 + back and forth; give the circle’s action infinite + back and forth. Only the circle loops forever.
-
Tune runs on and conditional playback. Set runs on to just the pages that use the interaction. Open conditional playback and choose a prefers-reduced-motion behavior (disable or skip to end) and the breakpoints the animation should run on.