Timeline labels
Timeline labels are named time positions you attach to a GSAP timeline with `addLabel()`, then reference by name to place tweens, seek the playhead, or start playback. They turn a timeline's raw seconds into readable anchors, so you sequence against `"reveal"` instead of hardcoding `1.4`.
Updated July 1, 2026
How timeline labels work
A label is just a name pinned to a time on the timeline. addLabel(name, position) records it, and from then on you can pass that name anywhere GSAP expects a position: the third argument of a tween, a seek() target, or a play() start point. If you omit the position, the label lands at the current end of the timeline.
Because the subhead and CTA are placed relative to "reveal", retiming the hero tween shifts everything downstream automatically. You never touch the numbers below the label. That is the whole point: the label is the single source of truth for a moment in the sequence.
Seeking and playing by name
Labels double as jump targets. seek() moves the playhead without playing, play() resumes from a label, and tweenTo() / tweenFromTo() animate the playhead between two labels with their own duration and ease.
Passing a string as the position adds a label too
tl.add("loopStart", 3.2) is shorthand for addLabel("loopStart", 3.2). GSAP's horizontalLoop helper leans on this to drop a label at the exact time each item reaches the start of the strip, so it can later tweenTo any item by name.Use timeline labels for
- Sequences you retime often - anchor downstream tweens to
"reveal"so shifting one beat cascades the rest - Named jump targets -
seek("outro")orplay("step2")for menus, wizards, and multi-state UI - Looping strips where you need to scroll to a specific item by index (
tweenTo("label3")) - Coordinating several tweens to share one start moment - place them all at the same label
- Self-documenting timelines -
"menuOpen"reads better than the raw number 0.85 in a 40-line sequence
Use something else when
- The sequence is two or three appended tweens - the default end-to-end chaining is already clear, labels add noise
- You only need 'same start as the previous tween' - the
"<"position keyword does that without naming anything - You want a fixed offset from the previous tween -
"+=0.3"/"-=0.2"is enough, no label required - You need the playhead to stop mid-timeline and wait - that is
addPause(position, callback), a different tool than a label
Used in these Annnimate components
Labels are core GSAP, not a plugin, and GSAP runs on roughly 2.2% of all websites (w3techs, June 2026) where timelines are the standard way to choreograph multi-step motion. Two Annnimate components sit on opposite ends of the label spectrum:
- The Marquee uses labels directly - it drops a named label at the timeline time each item reaches the start of the strip, then calls
tweenTo(label)to glide the loop to any specific item on demand - The Multi Flip builds a paused Flip timeline and places every card's tween at a computed numeric position (
index * stagger). It uses raw position parameters rather than names, which is exactly the case a label would make readable if the sequence grew a second coordinated beat
Labels do not move existing tweens
addLabel("reveal") only records a time. It never reflows tweens you already placed. If you add a label after building the timeline expecting earlier tweens to snap to it, nothing happens - place the tweens against the label as you build, not after.See it running in production
Common questions
- What's the difference between a label and the position parameter?
- The position parameter is the argument that decides WHERE a tween goes on the timeline - it accepts an absolute time (
1.2), a relative offset ("+=0.5"), a keyword ("<",">"), or a label name. A label is one of the things you can pass as that position. So labels don't replace the position parameter, they give it human-readable names to point at. - Does addLabel move or delay my tweens?
- No. A label is a passive marker - it just stores a name and a time in
tl.labels. Adding one never reflows existing tweens. To make a tween sit at a label, you have to pass the label name as that tween's position parameter when you add it (tl.to('.x', {...}, 'reveal')). - How do I start playback from a specific label?
tl.play("labelName")jumps to the label and plays forward.tl.seek("labelName")moves the playhead there without playing.tl.tweenTo("labelName")andtl.tweenFromTo("a", "b")animate the playhead to or between labels with their own duration and ease, which is how looping strips scroll smoothly to a chosen item.- What happens if I call addLabel without a position?
- The label lands at the current end of the timeline - whatever time the last-added tween finishes. That's why the common pattern is to build a few tweens, then
addLabel("reveal")to mark 'everything before this is the intro', then keep adding tweens relative to that label. - Can I place a tween slightly after a label?
- Yes. Labels take relative offsets like any position:
"reveal+=0.15"starts 0.15s after the label,"reveal-=0.1"starts 0.1s before it. This is the cleanest way to fan a few elements out from one shared moment without recomputing absolute times.
play(), pause(), reverse(), restart(), seek(), progress(), time(), and timeScale().NexttimeScaletimeScale is a GSAP method that changes the playback rate of a tween or timeline while it is running: timeScale(2) plays it at double speed, timeScale(0.5) at half speed, and timeScale(1) is normal.