Recipe 6.6

Applying a Transition When an Element Scrolls Into View

You can make content appear as it becomes visible with an animation effect. The element starts out hidden, and is observed with an IntersectionObserver. Once the element becomes partially visible, the style changes and an animated transition is shown.

Scroll down in the container below and you’ll see some cats appear with a fade and scale effect.

Demo

Cat Pictures

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec neque scelerisque, ultrices metus ac, scelerisque quam. Aliquam quis erat condimentum, vestibulum arcu ut, viverra libero. Quisque turpis orci, mattis aliquet nulla non, consequat congue lorem. Quisque vitae scelerisque velit. Sed mollis sit amet eros sit amet accumsan. Aenean lobortis egestas magna at commodo. Nullam purus orci, cursus at metus id, consequat gravida leo. Donec rhoncus eget velit id egestas. Vivamus nec ipsum sit amet nulla luctus hendrerit quis et dolor. Vivamus imperdiet luctus turpis et placerat. Maecenas hendrerit gravida mi, vitae suscipit nisi sodales eu. Fusce ac pretium turpis, nec ultrices mauris. In sem sapien, dictum quis elit vitae, euismod tristique ante. Donec interdum ullamcorper justo vel tempus

Vestibulum a ultricies elit, eu porttitor libero. Phasellus elementum suscipit nibh et ornare. Cras vulputate rhoncus dolor, vitae ullamcorper eros aliquet nec. Maecenas sollicitudin sed eros id tempor. Duis rutrum ac nibh id mollis. Fusce dapibus libero sapien, in posuere velit molestie ac. Praesent placerat tristique dictum. Sed sagittis magna nec nunc eleifend iaculis. Quisque interdum tincidunt euismod. In molestie ligula id felis tincidunt, et dapibus nisi auctor.

Scroll down to see the cats!

Code

JavaScript
const observer = new IntersectionObserver(entries => {
  // There are multiple images per row, so there are multiple
  // entries.
  entries.forEach(entry => {
    // Once the element becomes partially visible, apply the animated transition
    if (entry.isIntersecting) {
      entry.target.classList.add('appear');

      // No need to observe this element any further
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.25 }); // Fires when images become 25% visible

// Select all images tagged with the `animate` class and observe
// them.
document.querySelectorAll('img.animate').forEach(image => {
  observer.observe(image);
});
HTML
<style>
  .container {
    height: 20rem;
    overflow: auto;
  }

  .cats {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
  }

  img.animate {
    opacity: 0;
    transform: scale(0.5);
    transition: all 500ms;
  }

  img.animate.appear {
    opacity: 1;
    transform: scale(1);
  }
</style>

<div class="container">
  <h1>Cat Pictures</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec neque scelerisque, ultrices metus ac,
    scelerisque quam. Aliquam quis erat condimentum, vestibulum arcu ut, viverra libero. Quisque turpis orci, mattis
    aliquet nulla non, consequat congue lorem. Quisque vitae scelerisque velit. Sed mollis sit amet eros sit amet
    accumsan. Aenean lobortis egestas magna at commodo. Nullam purus orci, cursus at metus id, consequat gravida leo.
    Donec rhoncus eget velit id egestas. Vivamus nec ipsum sit amet nulla luctus hendrerit quis et dolor. Vivamus
    imperdiet luctus turpis et placerat. Maecenas hendrerit gravida mi, vitae suscipit nisi sodales eu. Fusce ac pretium
    turpis, nec ultrices mauris. In sem sapien, dictum quis elit vitae, euismod tristique ante. Donec interdum
    ullamcorper justo vel tempus
  </p>

  <p>
    Vestibulum a ultricies elit, eu porttitor libero. Phasellus elementum suscipit nibh et ornare. Cras vulputate
    rhoncus dolor, vitae ullamcorper eros aliquet nec. Maecenas sollicitudin sed eros id tempor. Duis rutrum ac nibh id
    mollis. Fusce dapibus libero sapien, in posuere velit molestie ac. Praesent placerat tristique dictum. Sed sagittis
    magna nec nunc eleifend iaculis. Quisque interdum tincidunt euismod. In molestie ligula id felis tincidunt, et
    dapibus nisi auctor.
  </p>

  <h2>Scroll down to see the cats!</h2>

  <div class="cats">
    <img class="animate" src="https://placekitten.com/400/200" />
    <img class="animate" src="https://placekitten.com/410/200" />
    <img class="animate" src="https://placekitten.com/420/200" />
    <img class="animate" src="https://placekitten.com/430/200" />
    <img class="animate" src="https://placekitten.com/440/200" />
    <img class="animate" src="https://placekitten.com/405/200" />
  </div>
</div>
Web API Cookbook
Joe Attardi