ZICUA
0123456789
0123456789
100

GSAP Motion Systems That Survive Production

A motion system survives production when animation is specified as reusable rules — duration and easing tokens, a library of named behaviours, a performance budget, and a reduced-motion path — instead of one-off effects added the week before launch. We design and build those systems in GSAP for WordPress and custom frontends, and this page covers the GSAP-versus-CSS decision, scroll and page-transition architecture, the Core Web Vitals thresholds published by web.dev, WCAG 2.3.3 handling, and how we test before ship. The full method lives in our GSAP motion systems in production guide.

Key takeaways

  • Motion is a design system like any other: tokens for duration, easing, and distance; named behaviours reused across pages; written triggers and end states.
  • CSS covers single-element state changes; GSAP covers timelines, staggers, scroll sequences, and page transitions — see the matrix in our GSAP versus CSS guide.
  • Animate transform and opacity. Layout properties force layout and paint work that eats the budget your Core Web Vitals depend on.
  • The budget is public: web.dev sets LCP at or under 2.5 seconds, INP at or under 200 milliseconds, CLS at or under 0.1.
  • Every animated surface ships with a prefers-reduced-motion path, as WCAG 2.3.3 expects — our reduced-motion accessibility guide shows the patterns.

What is a motion system in a design project?

A motion system is the set of rules that decides how things move in a product: how long, how far, with which easing, triggered by what, and what happens when motion is turned off. Without one, every page invents its own 300ms ease-in-out, hover states disagree with page transitions, and the site stops feeling like one brand. With one, designers specify from the same vocabulary developers implement — durations like quick (150ms), base (400ms) and emphasis (800ms); easings like a snappy exit ease or a soft landing; distances in rem or viewport units rather than magic pixels.

In practice we deliver four artefacts with every motion build. First, a motion inventory: every transition and interaction in the design, with trigger, duration, easing, and end state. Second, tokens expressed as CSS custom properties and as a GSAP defaults object so both stylesheets and scripts read the same numbers. Third, a behaviour library — fade-up, reveal, stagger-in, page wipe — implemented once and referenced by name. Fourth, fallback states: what the element looks like with reduced motion, with JavaScript unavailable, or on a slow connection. Motion work is scoped the same way in our motion sprint engagements when an agency needs a system without committing to a full site rebuild.

GSAP or CSS — which tool does the job?

We default to CSS for small, self-contained changes and reach for GSAP when sequencing, scroll dependency, or orchestration enters the picture. CSS transitions and animations stay in the stylesheet, cost no JavaScript, and are trivially overridden by a reduced-motion media query. GSAP earns its place when one trigger drives many properties across many elements, when timelines need labels and reversibility, or when scroll position itself is the input. The detailed decision tree is in GSAP versus CSS: when to use which; the working matrix we apply looks like this:

ScenarioToolWhy
Button hover colour, underline, small scaleCSS transitionOne element, one or two properties, no sequencing; no JS shipped for it
Focus rings, active states, simple accordion openCSS transition or animationState-driven, browser-native, automatically respects user motion settings when written with media queries
Fade-up entrance for a handful of elementsCSS with IntersectionObserver, or GSAP if already loadedEither is fine; pick one approach per project so behaviour stays consistent
Staggered list or grid entranceGSAP staggerSequencing, per-item delays, and reversal without writing per-child CSS
Pinned scroll story, scrubbed progress, parallax layersGSAP ScrollTriggerScroll-linked timelines, pinning with refresh handling, and predictable maths across browsers
Page transition between WordPress templatesGSAP timelineExit and enter choreography with labels, easing consistency, and easy revert on interruption
SVG line draw or multi-step hero revealGSAP timelineStroke and transform control in one timeline, with reduced-motion variants via matchMedia

Two rules keep the matrix honest: do not load GSAP to do what one CSS transition does, and do not hand-roll scroll logic in JavaScript when ScrollTrigger already solves refresh, resize, and cleanup.

How do we architect scroll sequences?

Scroll sequences fail in production for boring reasons: triggers that never get cleaned up, pins that fight the mobile layout, and animations that start before images finish loading. Our architecture prevents those first. Work starts from the motion inventory — each scene gets a trigger point (a named element or section offset), a mode (toggle-once, replay, or scrubbed), a pin duration where relevant, and a defined end state that is also the reduced-motion state.

Implementation follows three structural rules. One timeline per section, built with shared defaults from the token set, so a global easing change is a one-line edit. All triggers created inside a scoped context so an editorial refresh or a partial re-render can revert them cleanly instead of leaking listeners. Breakpoint behaviour declared with GSAP matchMedia rather than resize handlers: below the agreed width, pins and scrubs are killed and the same content renders as a static stacked layout — motion that makes sense on desktop does not automatically make sense on a 360px phone.

Lifecycle handling is where production builds differ from demos. We call ScrollTrigger refresh after fonts and hero images settle, because a late-loading font changes section heights and would otherwise leave triggers pointing at stale coordinates. Interaction-heavy scripts initialise lazily: a scene far below the fold does not build its timeline until it approaches the viewport. And after any back-forward cache restore we guard against double initialisation, so a returning visitor does not get two timelines fighting over the same elements. The same discipline applies when motion is layered onto commerce flows or marketing templates; related sequencing patterns appear in our motion web development work and in builds such as Switch Sound & Music.

How do page transitions work without wrecking performance?

Page transitions in a multi-page WordPress build follow a strict pattern. On an internal link click — same origin, no new tab, no modifier key — we play a short exit timeline that moves only transform and opacity, then navigate. The next page arrives with its content already present; JavaScript only plays an enter accent. Content is never hidden by default waiting for an animation, so a failed script or a slow connection still shows a readable page. Total perceived overhead stays low: the exit is measured in a few hundred milliseconds, not seconds, and it never gates access to the next page’s content.

Three details decide whether this survives contact with real users. Interrupted transitions are handled: if the visitor clicks again or presses back, the timeline reverts instead of leaving an overlay stuck on screen. Browser back-forward cache restores are detected and the transition layer is reset to hidden immediately. And click handlers stay light — building a heavy timeline synchronously inside the input handler adds input delay, which is exactly what INP measures. Our page transitions and INP guide walks through that trade-off in depth; the short version is that motion code must never be the reason an interaction misses the 200ms INP threshold.

What performance budget does motion get?

Motion code counts against the same budget as everything else. web.dev publishes the Core Web Vitals thresholds we build to: Largest Contentful Paint at or under 2.5 seconds, Interaction to Next Paint at or under 200 milliseconds, and Cumulative Layout Shift at or under 0.1. Animation libraries are deferred, never render-blocking, and every scene we add is weighed against what it costs on a mid-range phone rather than what it looks like on a laptop in a demo.

Property choice is the largest lever. Transform and opacity can be updated by the compositor without recalculating layout, which is why our tokens and timelines stick to them. Animating top, left, width, or height forces layout work on every frame; full-screen blur filters and continuously animated shadows are paint-heavy; both are avoided or pre-baked. will-change is treated as a hint, not a cure — MDN documents that it consumes memory, so we apply it just before a heavy sequence and remove it afterwards rather than spraying it across the stylesheet.

The second lever is the main thread, because INP measures how quickly the page responds to taps, clicks, and keys. Timelines are prepared ahead of input rather than assembled inside handlers, scroll work is batched, and continuous loops pause when their section leaves the viewport. Images carry explicit dimensions so entrance animations cannot introduce layout shift, and fonts load without reflowing the hero. The result is motion that is visible without being expensive.

How do we handle prefers-reduced-motion and WCAG 2.3.3?

WCAG 2.3.3, Animation from Interactions, expects that motion triggered by an interaction can be switched off unless the animation itself carries essential information. Most scroll stories, parallax layers, and page wipes fail that test — they are decoration over content that can be shown statically. We treat the reduced-motion version as a designed state, not a degraded one: the same hierarchy, without the travel.

Technically we cover both layers. CSS receives a prefers-reduced-motion media query that short-circuits transitions and keyframes. GSAP receives a matchMedia rule that sets elements to their final states with instant sets, kills scrubs and pins, and leaves the static composition in place — content visible, focus order intact, no interaction depending on an animation finishing. Progressive enhancement is the base layer: without JavaScript the page still renders complete, because hidden-until-animated defaults are a accessibility bug waiting for a script error. Patterns, pitfalls, and checklist language for audits are in our prefers-reduced-motion accessibility guide.

How do we test motion before launch?

Emulation is not enough for motion. We run every build on real devices — at minimum a current iPhone in Safari and a mid-tier Android in Chrome — because scroll feel, thermal throttling, and compositor behaviour differ from desktop simulation. In the lab we profile with CPU throttling in Chrome DevTools, watch for long tasks during transitions, and run Lighthouse against key templates for LCP and CLS. Interaction timing gets explicit attention: every interactive element is tapped and clicked while we watch input delay, because INP regressions usually trace back to one heavy handler, not to the whole animation library.

Lifecycle cases are on the test script too: resize and rotate, font swap on slow networks, back-forward cache restore, reduced motion toggled on and off, and JavaScript partially blocked to confirm content still reads. Each behaviour in the motion inventory is checked at every breakpoint, including the matchMedia kill paths — a pin that was removed on mobile must actually be gone. After launch we watch field data rather than lab scores alone, since real INP comes from real devices on real networks. When an agency needs this applied to an existing site without a rebuild, the scoped route is a motion sprint; larger programmes run through our guides hub or a full motion web development engagement.

FAQ

Do we need GSAP if CSS can animate?

Not for simple state changes — use CSS there. GSAP earns its place when you need sequencing, staggers, scroll-linked timelines, pinning, or page transitions with reversible exit states. The split is documented in when to use GSAP versus CSS.

Will GSAP hurt our Core Web Vitals?

Not if it is deferred, scoped, and animating transform and opacity. The risks are render-blocking loading and heavy work inside input handlers — both of which we design out against the web.dev thresholds for LCP, INP, and CLS.

How do you make page transitions accessible?

Keep content present before animation, skip the transition under prefers-reduced-motion, never trap focus, and keep handlers light so INP stays within 200ms. Our page transitions and INP guide details the pattern.

What happens when a visitor turns animations off?

Elements render at their final states through our matchMedia rules: no hidden content, no pinned sections, no scroll traps. The reduced-motion version is designed alongside the animated one, per WCAG 2.3.3.

How long does a motion system take to build?

An inventory, token set, and library of four to six behaviours for a marketing site usually lands within a focused sprint; full scroll stories and transitions extend the window. Scope variables are covered in how a motion sprint works.

Can you add motion to an existing WordPress site?

Yes. We audit performance headroom first, define the inventory, then layer GSAP behind deferred scripts with reduced-motion fallbacks. Projects like Mukani and Leadly show the range from restrained to expressive.