gsap-core-timelines
GSAP core: tweens and timelines
When to use this
- You need two or more animations to run in a precise relative order: fully sequential, overlapping by a fixed amount, or starting at the exact same instant.
- You are building a multi-step entrance/exit sequence (hero section, modal, onboarding) where the order and overlap of steps is the actual design, not just individual element timing.
- You need
repeat,yoyo, or keyframe-based multi-stop tweens on a single element without hand-rolling a timeline. - You want one
defaultsobject to govern ease/duration for a whole sequence instead of repeating the same three properties on every call. - Do NOT use this when the animation is scroll-driven (use
gsap-scrolltrigger), when you are animating a layout change between two DOM states (usegsap-flip-layout), or when you only need a single independent CSS transition with no sequencing (plain CSS is lighter).
Mental model
GSAP's tween is a value interpolator with a lifecycle, not a CSS transition wrapper. gsap.to(target, vars) reads the target's current value for each animated property, computes an end value from vars, and on every ticker frame (driven by requestAnimationFrame through GSAP's own internal ticker, not per-element rAF calls) computes the eased interpolated value and writes it directly to the property (inline style for DOM, or object property for plain JS objects). Because GSAP owns a single global ticker, every active tween across the page is stepped in the same frame, which is why GSAP timelines can keep frame-perfect sync between children even under load, unlike independently-started CSS transitions.
A gsap.timeline() is a container tween: it has its own internal playhead (a number of seconds) and every child tween's position is stored as an offset on that playhead, not as a wall-clock delay. When you call .play(), .pause(), .seek(), .timeScale(), or .reverse() on the timeline, GSAP recalculates every child's rendered state from the timeline's playhead position, which is what makes reversing or scrubbing a whole multi-step sequence trivial and glitch-free: it is not "run the animations backward," it is "render the state at playhead time T," where T can move in either direction or jump discontinuously.
The position parameter (the third argument to .to()/.from()/.fromFrom() when added to a timeline) places a child's start time on that playhead relative to either the end of the previously-added child (default) or an absolute/label/relative offset you supply. This is the single most important piece of GSAP syntax: "-=0.3" means "start 0.3s before the previous child ends" (overlap), "+=0.3" means "0.3s after it ends" (gap), "<" means "at the same start time as the previous child," and a bare number or a label string means an absolute position on the timeline's own clock. Labels (tl.addLabel('name')) are just named bookmarks on that same playhead, letting you insert or jump to points without recalculating offsets by hand.
gsap.from() runs the interpolation in reverse conceptually: it captures the current value as the end state and animates FROM the values you specify TO that captured end state. gsap.fromFrom() (typo aside, it is fromTo()) takes explicit start and end values for full control, useful when the element's current computed style is not a safe assumption for either endpoint.