Skip to main content
March 23, 2026Dan Rodney/9 min read

GSAP Timelines: Animating Multiple Elements in Sequence

Master Sequential Animations with GSAP Timeline Methodology

GSAP Timeline Core Concepts

Sequential Animation

Control multiple elements to animate one after another in a coordinated sequence. Eliminates manual delay calculations.

Timeline Management

Create reusable animation sequences that can be paused, reversed, or controlled as a single unit.

Position Parameters

Fine-tune timing with relative and absolute positioning to create sophisticated animation choreography.

Topics Covered in This JavaScript Tutorial:

Master GSAP's powerful timeline system by animating multiple elements in sequence, implementing clean chaining syntax, and leveraging timeline repeat functionality with RepeatDelay properties for professional web animations.

Exercise Preview

preview gsap timeline

Exercise Overview

In this comprehensive exercise, you'll advance beyond basic GSAP animations to master timeline orchestration—a critical skill for creating sophisticated, sequenced animations that form the backbone of modern interactive web experiences. You'll learn to coordinate multiple elements, control timing with precision, and build reusable animation sequences that can be controlled programmatically.

Getting Started

Let's establish our development environment and examine the project structure we'll be working with.

  1. Navigate to the GSAP Timeline folder located in Desktop > Class Files > JavaScript Class. Open this folder in your code editor (Visual Studio Code, Sublime Text, or your preferred editor with folder support).
  2. In your code editor, open timeline.html from the GSAP Timeline folder to examine the project structure.
  3. Preview timeline.html in Chrome to see the starting state.

    You'll see a static logo similar to our previous exercise, but notice we've added a tagline below it. This dual-element setup will demonstrate the power of timeline sequencing.

  4. Back in your code editor, examine the HTML structure within the body tag:

    <img id="logo" src="img/noble-desktop-logo.svg" ALT="Noble Desktop">
    <p id="tagline">Design. Code. Create.</p>
  5. Note the semantic IDs on both elements: logo and tagline. These descriptive identifiers will serve as our animation targets and make our code more maintainable.

Setup Requirements

0/3

Loading the GSAP JavaScript Library

Before we can harness GSAP's animation capabilities, we need to properly include the library in our project.

  1. Add the GSAP library reference just before the closing </body> tag. This placement ensures the DOM is fully loaded before our animations execute:

    </main>
       <script src="js/gsap.min.js"></script>
    </body>
  2. Create a dedicated script block for our custom animation code below the library import:

    <script src="js/gsap.min.js"></script>
       <script></script>
    </body>

Animating the First Element

We'll begin by creating our initial animation using GSAP's from() method, which defines where an element starts and animates to its natural position.

  1. Initialize your first GSAP animation with the basic method call:

    <script>
        gsap.from();
    </script>
  2. Configure the animation parameters to create a dynamic entrance effect for the logo:

    gsap.from('#logo', {duration:1, scale:0, y:100});

    This animation starts the logo at zero scale and 100 pixels below its final position, then animates to its natural state over one second.

  3. Save your file and reload the page in Chrome.

    The logo should scale up from nothing while moving upward into position, creating an engaging entrance effect.

Animating Additional Elements

Now we'll add the tagline animation. Initially, we'll demonstrate the limitations of independent animations before showing how timelines solve these challenges.

  1. Duplicate the logo animation to create a foundation for the tagline animation:

    <script>
       gsap.from('#logo', {duration:1, scale:0, y:100});
       gsap.from('#logo', {duration:1, scale:0, y:100});
    </script>
  2. Modify the second animation to target the tagline element:

    gsap.from('#logo', {duration:1, scale:0, y:100});
    gsap.from('#tagline', {duration:1, scale:0, y:100});
  3. Save and reload the page in Chrome.

    Both elements animate simultaneously with identical effects. While interesting, this simultaneous animation lacks the sequential flow we're aiming for. We want the tagline to appear after the logo completes its animation.

  4. Return to your code editor to implement proper sequencing.
  5. Add a delay to the tagline animation to create the desired sequence:

    gsap.from('#logo', {duration:1, scale:0, y:100});
    gsap.from('#tagline', {duration:1, scale:0, y:100, delay:1});
  6. Save and reload the page in Chrome.

    Perfect! The logo animates for one second, then the tagline begins its animation with a one-second delay, creating a seamless sequence.

  7. Switch back to your code editor for a visual enhancement.
  8. Create visual contrast by making the tagline animate from above rather than below:

    gsap.from('#tagline', {duration:1, scale:0, y:-100, delay:1});
  9. Save and reload the page in Chrome.

    The contrasting directions (logo from below, tagline from above) create a more dynamic and visually interesting sequence.

Independent vs Timeline Animations

FeatureIndependent TweensTimeline Approach
Timing ControlManual delay calculationsAutomatic sequencing
MaintenanceComplex when scalingEasy to modify
Playback ControlCannot pause/reverseFull control available
Code OrganizationScattered tweensUnified timeline object
Recommended: Timeline approach provides superior control and maintainability for multi-element animations

Creating & Using a Timeline

While our delay-based approach works for simple sequences, it becomes unwieldy and fragile as complexity grows. GSAP timelines provide a robust solution that offers superior control, maintainability, and flexibility for complex animation sequences.

  1. Return to your code editor to implement our first timeline.
  2. Create a new timeline instance that will serve as the container for our animation sequence:

    let tl = gsap.timeline();
    gsap.from('#logo', {duration:1, scale:0, y:100});
    gsap.from('#tagline', {duration:1, scale:0, y:-100, delay:1});
  3. Attach our animations to the timeline instead of calling them independently:

    let tl = gsap.timeline();
    tl.from('#logo', {duration:1, scale:0, y:100});
    tl.from('#tagline', {duration:1, scale:0, y:-100, delay:1});
  4. Save and reload the page in Chrome.

    Notice the timing has shifted slightly. The timeline automatically sequences animations, so each one begins after the previous animation completes. The logo still takes one second, but now the tagline waits for the logo to finish, then waits an additional second due to its delay property.

  5. Remove the redundant delay since the timeline handles sequencing automatically:

    let tl = gsap.timeline();
    tl.from('#logo', {duration:1, scale:0, y:100});
    tl.from('#tagline', {duration:1, scale:0, y:-100});
  6. Save and reload the page in Chrome.

    Now the tagline animates immediately after the logo completes, creating a smooth, precisely timed sequence without manual delay calculations.

Timeline Implementation Process

1

Instantiate Timeline

Create timeline variable using gsap.timeline() method to serve as animation container

2

Replace Individual Calls

Change gsap.from() calls to timeline.from() using your timeline variable name

3

Remove Manual Delays

Delete delay properties since timeline handles sequencing automatically

4

Test Sequential Flow

Verify animations play in order without gaps or overlaps

Cleaning up the Syntax with Chaining

GSAP supports method chaining, allowing us to write more concise, readable code. This pattern is particularly valuable in complex animation sequences where clarity and maintainability are crucial.

  • Chain multiple methods from a single timeline reference
  • Use only one semicolon at the sequence end
  • Place each method on its own line for enhanced readability
  1. Remove the timeline reference from each individual method call:

    let tl = gsap.timeline();
    .from('#logo', {duration:1, scale:0, y:100});
    .from('#tagline', {duration:1, scale:0, y:-100});
  2. Remove the semicolons from intermediate method calls:

    let tl = gsap.timeline();
    .from('#logo', {duration:1, scale:0, y:100})
    .from('#tagline', {duration:1, scale:0, y:-100})
  3. Connect the chain to your timeline variable:

    let tl = gsap.timeline();
    tl.from('#logo', {duration:1, scale:0, y:100})
      .from('#tagline', {duration:1, scale:0, y:-100})
  4. Save and reload the page in Chrome.

    The animation behavior remains identical, but your code is now more maintainable and follows industry best practices for method chaining.

Method Chaining Benefits

Chaining timeline methods creates cleaner, more readable code. Use format: tl.from().to().from() with single semicolon at end and timeline name only once at beginning.

Adding More Elements to the Timeline

The timeline's sequential nature makes adding new animations straightforward—each new animation automatically follows the previous one in the sequence, eliminating the need for complex delay calculations.

  1. Add a rotation effect to the logo that occurs between the scale animation and the tagline entrance:

    tl.from('#logo', {duration:1, scale:0, y:100})
      .to('#logo', {duration:1, rotate:360})
      .from('#tagline', {duration:1, scale:0, y:-100})

    Note that we're using to() instead of from() because we want to animate from the current state to a rotated state.

  2. Save and reload the page in Chrome.

    Observe the carefully orchestrated sequence:

    • Logo scales up and moves into position
    • Logo rotates 360 degrees
    • Tagline scales up and moves into position
    This demonstrates how timelines make complex sequences both predictable and maintainable.

Adjusting Timing with the Position Parameter

While sequential timing works well for many scenarios, professional animations often require more nuanced timing control. GSAP's position parameter provides powerful tools for fine-tuning when animations start relative to each other.

The position parameter accepts various formats:

tl.from(target, {vars}, position)
  1. Add a one-second pause before the logo rotation by using a relative position parameter:

    tl.from('#logo', {duration:1, scale:0, y:100})
      .to('#logo', {duration:1, rotate:360}, '+=1')
      .from('#tagline', {duration:1, scale:0, y:-100})

    The +=1 parameter tells GSAP to start this animation one second after the previous animation ends.

  2. Save and reload the page in Chrome.

    Notice the deliberate pause between scaling and rotation, which can create dramatic emphasis or allow viewers to process the initial animation.

  3. Create overlapping animations by starting the rotation before the scaling completes:

    .to('#logo', {duration:1, rotate:360}, '-=.5')

    The negative value starts the rotation 0.5 seconds before the previous animation ends.

  4. Save and reload the page in Chrome.

    The overlapping effects create a more dynamic, fluid animation where scaling and rotation occur simultaneously for part of the sequence.

  5. Use absolute positioning to start the tagline at exactly 3 seconds from the timeline's beginning:

    .from('#tagline', {duration:1, scale:0, y:-100}, 3)
  6. Save and reload the page in Chrome.

    The tagline now appears at exactly the 3-second mark, regardless of when the previous animations finish.

  7. Synchronize the tagline with the logo rotation using the convenient start-alignment parameter:

    .from('#tagline', {duration:1, scale:0, y:-100}, '<')
  8. Save and reload the page in Chrome.

    Both the rotation and tagline animations now start simultaneously, creating a coordinated effect. You can also use variations like '<2' to start 2 seconds after the previous animation begins. For comprehensive positioning options, refer to the official documentation at greensock.com/position-parameter.

Position Parameter Options

Relative Timing (+=/-=)

Use +=1 for delay after previous animation ends, or -=0.5 to start during previous animation. String values required.

Absolute Timing (numbers)

Use absolute numbers like 3 to start exactly 3 seconds from timeline start. No quotes needed for numeric values.

Synchronized Start (<)

Use < symbol to start exactly when previous animation begins. Add numbers like <2 for offset timing.

Timeline Repeat and Control Properties

One of the most powerful advantages of timelines is their ability to be controlled as a single unit. You can repeat, pause, reverse, or restart entire sequences with simple property changes.

  1. Add repeat functionality to your timeline by configuring it during creation:

    let tl = gsap.timeline( {repeat:2} );
  2. Save and reload the page in Chrome.

    The entire sequence now plays three times total (original plus two repeats), demonstrating how timeline properties affect the entire animation sequence.

  3. Add a pause between repetitions to let viewers appreciate the final state:

    let tl = gsap.timeline( {repeat:2, repeatDelay:2} );
  4. Save and reload the page in Chrome.

    The 2-second pause between repetitions creates a more professional, considered animation rhythm rather than jarring immediate repetition.

  5. Create an infinite loop for ongoing ambient animation:

    let tl = gsap.timeline( {repeat:-1, repeatDelay:2} );
  6. Save and reload the page in Chrome.

    The animation now cycles continuously with 2-second pauses, perfect for hero sections or ambient interface elements that need persistent visual interest.

Safari Rendering Bug Solution (MacOS and iOS)

In Safari browsers, timeline repetitions can cause visual artifacts where duplicate images appear during animation cycles. This browser-specific rendering issue requires a CSS optimization hint to resolve.

The CSS will-change property informs the browser's rendering engine that an element will undergo specific transformations, allowing it to optimize accordingly. According to MDN Web Docs: "The will-change CSS property hints to browsers how an element is expected to change. Browsers may set up optimizations before an element is actually changed."

Since GSAP animations utilize CSS transforms under the hood, we can prevent Safari's rendering glitch by explicitly declaring this intent:

#logo {
   will-change: transform;

Code Omitted To Save Space

}

Important: Use will-change sparingly and only when necessary, as it can impact performance if overused. Remove it when animations are complete in production applications.

Key Takeaways

1GSAP timelines provide superior control over multi-element animations compared to independent tweens with manual delays
2Timeline method chaining creates cleaner code syntax using single timeline reference with multiple from() and to() methods
3Position parameters offer flexible timing control with relative (+=/-=), absolute (numbers), and synchronized (<) positioning options
4Timeline animations can be repeated infinitely using repeat: -1, with repeatDelay adding pauses between cycles
5Sequential animations automatically play in the order they appear in code, eliminating complex delay calculations
6Safari requires CSS will-change: transform property to prevent visual artifacts during timeline repeats on macOS and iOS
7Timeline objects enable unified control for pausing, reversing, and managing entire animation sequences
8Method chaining reduces code complexity by using single semicolon at end and timeline name only at beginning

RELATED ARTICLES