DEV Community

Cover image for Reveal on Scroll with Nuxt and Intersection Observer API
Michael Synan
Michael Synan

Posted on • Originally published at michaelsynan.com

Reveal on Scroll with Nuxt and Intersection Observer API

While it's fun to add as many libraries to your project as possible (not really), sometimes it makes sense to use browser native solutions.

Enter Web Browser APIs.

One of my favorite Web Browser APIs is Intersection Observer, which provides an interface for determining if an element is located inside the viewport. This handy API has been around since 2017 and has been proven to be extremely stable and performant for aiding in such tasks as lazy loading, animations and effects, and tracking user engagement.

Using browser native solutions like the Intersection Observer API helps reduce load time and decreases the number of dependencies in your project.

You can read more about Intersection Observer here.

In this tutorial I'll demonstrate how to add Intersection Observer to your Nuxt 3 project in order to trigger a reveal on scroll CSS animation.

Intersection Observer Illustration

How Does it Work?

The Intersection Observer API works by creating a new observer instance which takes a callback function and options as its arguments. The callback function is executed whenever the target element intersects with the specified threshold in the viewport, defined in the options object. By invoking the observer's observe method and passing in the target element, you can efficiently monitor and react to its visibility changes on the page.

In order to use Intersection Observer to animate an element on scroll you'll need to use the onMounted() Vue.js hook.

To do this, simply import onMounted in the script section of your component template:

import { onMounted, ref } from 'vue';
Enter fullscreen mode Exit fullscreen mode

Intersection Observer

Next, you must create your Observer instance inside of the onMounted lifecycle hook and write your desired logic for any elements that get passed back, like so:

onMounted(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          entry.target.classList.add('animate-delay');
        }
      });
    },
    {
      threshold: 0.5,
    }
  );

  if (demo) {
    observer.observe(demo);
  }
});
Enter fullscreen mode Exit fullscreen mode

In the example above the CSS class "animate-delay" is appended to the class list of any element being observed.

CSS styles

With your Observer in place, you can wrap up by adding the desired CSS animations:

.animate-delay {
  animation-duration: 0.5s;
  animation-fill-mode: both;
  animation-name: animate-delay;
}

@keyframes animate-delay {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

.demo {
  display: inline-block;
  opacity: 0;
  transform: translateY(10px);
}
</style>
Enter fullscreen mode Exit fullscreen mode

In the demo code I added a ref to my target element called "demo" but you can use classes, IDs and any other DOM element:

<span ref="demo" class="demo">
  Intersection Observer in Action 👌
</span>
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

If you have any issues you can always use console.log inside of the Observer instance to check if your Observer instance is working correctly:

console.log('Observed element:', entry.target);
Enter fullscreen mode Exit fullscreen mode

Live Demo

If you want to see it in action, you can check out the live demo on StackBlitz: https://stackblitz.com/edit/intersection-observer-nuxt?file=README.md

Conclusion

In conclusion, using browser native solutions like the Intersection Observer API can greatly benefit the performance of your project by reducing load time and dependencies. The Intersection Observer API provides a stable and efficient solution for triggering animations and effects on scroll. By implementing this API in your Nuxt 3 project, you can easily create some nice animations and increase website performance.

Top comments (1)

Collapse
 
michaelsynan profile image
Michael Synan

To see an example with multiple elements check out this demo: stackblitz.com/edit/intersection-o...