← Back to the GSAP tutorial
Lesson

GSAP, Visually

GSAP (the GreenSock Animation Platform) is the JavaScript library pros use for animation that CSS can't do gracefully — precise sequencing, scroll-driven motion, and total playback control. This lesson teaches tweens, eases, staggers, timelines, and ScrollTrigger, with demos you can play and replay.

Step 1

Why reach for GSAP?

CSS animation is great for simple, self-contained motion. But when you need to sequence many steps, control playback (play, pause, reverse, scrub), animate any numeric property, or tie motion to scroll, hand-written CSS and JavaScript get painful fast. GSAP makes all of it short and reliable.

Use CSS when…Use GSAP when…
A hover, a single fade, a loading spinnerA multi-step sequence with precise timing
Motion that never needs to be controlled by JSYou need play / pause / reverse / scrub control
One element, one transitionDozens of elements with staggered offsets
Scroll-driven animation (ScrollTrigger)
GSAP is fast, framework-agnostic (works with anything you can select), and handles cross-browser quirks for you. It's used across Apple, Google, and countless award-winning sites.
Step 2

Loading GSAP

The fastest start is the CDN: one script tag gives you the global gsap object. Plugins like ScrollTrigger are separate files you register once.

<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="…/ScrollTrigger.min.js"></script>  <!-- optional plugin -->

<script>
  gsap.registerPlugin(ScrollTrigger);   register any plugins you load
  gsap.to('.box', { x: 200, duration: 1 });
</script>
This very page loads GSAP + ScrollTrigger from that same CDN — every demo below is real GSAP running live. (In a build tool, you'd npm install gsap and import it instead.)
Step 3

gsap.to() — the method you'll use most

gsap.to(target, vars) animates a target to the values you give. First argument: what to animate (a selector or element). Second: an object of end values plus options like duration and ease.

to
gsap.to('#box', {
  x: 240,          move 240px right (uses transform)
  rotation: 360,    spin once
  duration: 1,
  ease: 'power2.out'
});
GSAP animates x/y, not left/top — under the hood these become GPU-friendly transforms, so motion stays smooth. rotation, scale, and opacity work the same way.
Step 4

from() & fromTo() — entrances

gsap.from() animates from the values you give to the element's current (resting) state — perfect for entrances. fromTo() lets you specify both ends explicitly.

1
2
3
gsap.from('.item', {
  y: 40,         start 40px lower…
  opacity: 0,    …and invisible, then settle to normal
  duration: 0.6
});
from() is the secret to clean entrance animations: you build the page in its final layout, then tell GSAP where elements should animate from. No need to set a starting style yourself.
Step 5

The vars object

That second argument — the “vars” object — holds both the properties to animate and the special options that control the tween. The common ones:

KeyDoes
x, yMove (transform-based, in px).
rotation, scaleSpin and resize.
opacityFade in/out (0–1).
durationSeconds the tween lasts.
delaySeconds to wait before starting.
easeThe easing curve (Step 6).
repeat / yoyorepeat: -1 loops forever; yoyo: true reverses each repeat.
staggerOffset between multiple targets (Step 7).
onCompleteA function to run when it finishes.
You can animate almost any numeric CSS property and even SVG attributes: backgroundColor, borderRadius, width, strokeDashoffset… GSAP figures out how to interpolate it.
Step 6

Easing gives motion character

GSAP's eases go far beyond CSS. power2.out decelerates smoothly; back.out overshoots; elastic springs; bounce drops. Hit Run — same distance, same duration, very different feel:

none (linear)
power2.out
back.out(1.7)
elastic.out(1, 0.4)
bounce.out
power1–4.out covers most UI needs (higher = more dramatic deceleration). Save elastic and bounce for playful accents — they're attention-grabbing by design.
Step 7

Stagger: many elements, one tween

Add stagger and one call animates a whole group with a time offset between each — the cascading reveal you see everywhere. Replay this grid:

gsap.from('.dot', {
  scale: 0,
  opacity: 0,
  duration: 0.4,
  stagger: 0.04   40ms between each dot
});
stagger can also be an object — stagger: { each: .05, from: 'center' } — to ripple out from the center, edges, or a grid position.
Step 8

Timelines: sequencing

A timeline chains tweens so they run in order — no manual delay math. Tweens added to a timeline play one after another by default, and you can overlap them with position offsets. The whole timeline is one controllable object.

1
2
3
const tl = gsap.timeline();
tl.from('.box1', { y: -40, opacity: 0 })
  .from('.box2', { y: -40, opacity: 0 })    runs after box1
  .from('.box3', { y: -40, opacity: 0 }, '-=0.2'); overlaps by .2s
Because a timeline is one object, you can tl.pause(), tl.reverse(), tl.timeScale(2) (double speed), or scrub it with a slider — control you simply can't get from CSS keyframes.
Step 9

ScrollTrigger: animate on scroll

The most popular GSAP plugin. ScrollTrigger ties any tween to the scroll position — play when an element enters the viewport, or scrub an animation as you scroll. The box below animates in the moment it scrolls into view:

scroll

(Scroll this section into view, or reload near it, to trigger it.)

gsap.registerPlugin(ScrollTrigger);

gsap.from('.reveal', {
  y: 60, opacity: 0, duration: 0.8,
  scrollTrigger: {
    trigger: '.reveal',
    start: 'top 85%'   when the top hits 85% down the screen
  }
});
Add scrub: true to tie progress directly to the scrollbar (the animation rewinds as you scroll up), or pin: true to lock an element in place while a sequence plays — the foundation of modern scroll-telling sites.
Step 10

GSAP checklist

Where next

Keep going