0Pricing
HTML Academy · Lesson

Scroll-Linked Animations Setup

Trigger CSS animations when elements enter the viewport.

Scroll-Linked Animations Setup is a free HTML Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Goal

Scroll-linked animations play, pause, or reverse based on element visibility. Examples: a hero fade-in when a section scrolls into view, a number that counts up when visible, a parallax effect tied to scroll position. IntersectionObserver triggers the animations; CSS or the Web Animations API runs them.

Trigger-Based Animations

The simplest pattern: when an element enters the viewport, add a CSS class that contains the animation. entry.target.classList.add("in-view") in the observer callback; the class defines animation: fade-in 600ms forwards.

.fade-up { opacity: 0; transform: translateY(20px); }
.fade-up.in-view {
  animation: fadeUp 600ms cubic-bezier(.2,.8,.2,1) forwards;
}
@keyframes fadeUp {
  to { opacity: 1; transform: none; }
}

Observer Setup

Create a shared observer, observe every element with the trigger class, add "in-view" on intersection, unobserve to avoid re-triggering. For one-shot animations this is all you need; for repeat-on-re-enter, do not unobserve and remove the class on exit.

const observer = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    if (entry.isIntersecting) {
      entry.target.classList.add("in-view");
      observer.unobserve(entry.target);
    }
  }
}, { threshold: 0.2 });
document.querySelectorAll(".fade-up").forEach((el) => observer.observe(el));

Stagger Effects

For sequential reveal of a list, apply a per-item delay via CSS custom property: style="--delay: ${i * 100}ms" on each item; the animation reads animation-delay: var(--delay). Items animate in cascade as the list enters view.

Threshold for Earlier Trigger

threshold: 0.2 fires when 20% of the element is visible — usually a good moment for "in-view" animations. threshold: 0 fires too early (any pixel) and looks abrupt; threshold: 1 fires too late (fully visible) and feels delayed.

Scroll-Linked vs Scroll-Triggered

Scroll-triggered animations play once on intersection (covered above). Scroll-linked animations advance their progress in lockstep with scroll position. The modern way is CSS scroll-driven animations (animation-timeline: scroll()), with IntersectionObserver still useful for entering/exiting trigger zones.

Avoiding Layout Thrash

Animate properties the GPU can transform cheaply: transform and opacity. Avoid animating top, left, width, height — they trigger layout on every frame, which makes scroll-tied animations stutter on mid-range devices.

Respect Reduced Motion

Wrap animation declarations in @media (prefers-reduced-motion: no-preference) so users who request reduced motion (vestibular disorders, sensitivity) get the static end-state without movement. Decorative animations should disable entirely under reduced motion.

.fade-up { opacity: 1; transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .fade-up { opacity: 0; transform: translateY(20px); }
  .fade-up.in-view { animation: fadeUp 600ms forwards; }
}

Performance Pattern

Use a single shared observer (not one per element). Use unobserve once a one-shot animation has fired. Use will-change sparingly — only on elements currently animating, and remove it when the animation ends. Watch the Performance panel for dropped frames.

Bidirectional Animations

For animations that should reverse when the element leaves the viewport, do not unobserve. In the callback, toggle the class based on isIntersecting: entry.target.classList.toggle("in-view", entry.isIntersecting). The animation runs forward on entry and reverses on exit.

Combining With Web Animations API

For JS-driven animations, replace classList.add with entry.target.animate(keyframes, options). WAAPI returns an Animation object you can pause, reverse, or chain via promises — more flexible than CSS for complex sequences.

Knowledge Check

Why is animating transform and opacity preferred over animating top/left/width/height in scroll-linked animations?

Summary

Scroll-linked animations combine IntersectionObserver with CSS animation classes or WAAPI. Set a hidden state, add "in-view" on intersection, animate transform and opacity (not top/left), respect prefers-reduced-motion, stagger via CSS custom properties for cascading reveals. For full scroll-progress animations, consider native scroll-driven animations (animation-timeline: scroll()).

Frequently asked questions

Is the “Scroll-Linked Animations Setup” lesson free?

Yes — the full text of “Scroll-Linked Animations Setup” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.

What will I learn in “Scroll-Linked Animations Setup”?

Trigger CSS animations when elements enter the viewport. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start HTML Academy?

No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Scroll-Linked Animations Setup” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this HTML Academy lesson?

Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. IntersectionObserver API and Thresholds
  2. Lazy Loading with IntersectionObserver
  3. Infinite Scroll Implementation
  4. Scroll-Linked Animations Setup
← Back to HTML Academy