What is Intersection Observer?
The IntersectionObserver interface of the Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport. The ancestor element or viewport is referred to as the root.
Let’s Build an Observer
When I first started experimenting with Intersection Observer, I quickly learned that it’s easier to experiment and learn from trial and error and then refer back to the documentation. The pen below is the full example of the demo I put together for this article, which you can use to follow along with.
Intersection Observer Options
By default, Intersection Observer has three properties that are read-only and cannot be modified once set. These properties are
thresholds. Each property can modify how the observer behaves while it’s running. For a full definition of each property checkout the MDN documention.
The first property,
root, is the container that that will act as our viewport area. When the element that is being observed is inside of this container it will have the property of isIntersecting: true. If the element falls outside of the viewport then
isIntersecting is set to false. Setting a value of null will allow you to set your root as the document viewport instead of a specific element.
rootMargin property adds margin around the root very similar to CSS. This value is optional and defaults to “0px 0px 0px 0px.” For example, if the root is set to the document viewport, and you had a rootMargin of 20px, then the observed element would be intersected 20px before the element passes outside of the root container. This value can also use percentages in place of pixels.
thresholds property defines how far an element needs to intersect the root element. Using 0.7 as a threshold means that 70% of the observed element needs to be inside the root element. It’s important to know that using
threshold will allow the use of only one value. Meanwhile,
thresholds allows the use of an array of numerical values, which would be helpful if I were running multiple Intersection Observer instances and wanted them to behave differently.
Creating a New Observer
blurscroll ┣ blur.js ┣ dino-reichmuth-A5rCN8626Ck-unsplash.jpg (replace this with your own image). ┣ index.html ┗ style.css
HTML document – index.html
In index.html, I created an
<img> element that will be targeted by the Intersection Observer. Next, I added a
<script> tag that points to the blur.js file located in the same directory. The script tag is imported.
Adding Styles – styles.css
In style.css, I set the minimum height to be 200% of the viewport so the visible area is scrollable. Next, I added some styles to center the image in the content area. For this code example, I set the max-height of 100% of the viewport so that the scroll effect can be viewed in a very small viewport, such as a Code Pen editor.
Setting up Intersection Observer – blur.js
This file will check for an image and add or remove an inline style for a CSS blur filter. Now that the blur.js file is linked in the HTML, it’s time to create the Intersection Observer.
1. Defining Options
The first variable,
heroImage, is checking for an image element in the HTML. The second variable,
options, is an object with the root, rootMargin, and threshold properties that will be used in our Intersection Observer instance. By setting
root: null, the observer will default to the edge of the browser viewport. The
rootMargin is defined as 0px, so the observer still defaults to the edge. Lastly, I set the
threshold of 0.7, which is easier to think of as 70%. When the image is less than 70% visible, that’s when our observer will activate.
2. Callback Function
The callback function is executed while an element is being observed. In this example, I’m creating the variable
callback and assigning a function to it. The callback function takes in a list of
IntersectionObserverEntry objects and the observer that will be created in Step 3, as seen below.
Next, I’m logging the entry objects so the interface can be viewed in the console, and then I’m rendering some inline CSS on the image element. Depending on the true or false condition of
isIntersecting, a CSS blur filter will be added or removed. During the initial load,
isIntersecting is true so the blur is set to 0. When scrolling beyond, the threshold value changes to false, which will apply a blur with a value of 10px.
Note: Since I’m only observing a single element for this demo, I selected the first entry in the array with
entries. If I were targeting multiple elements on a page, I would loop through all of the available elements instead.
3. Intersection Observer Constructor
- Now that the initial variables are created and the callback function is in place, I’m going to set up a new instance of Intersection Observer by using the
IntersectionObserver()and assigning that to the variable
- Then, I’m passing in the callback function and options variable into the parameters.
- Lastly, it’s time to run the observer on the image element, using the observe() method on the observer variable I passed in the
heroImageto observe the image element.
In this example, I want the observer to start observing when
heroImage has been located and continuously check if the image is intersecting while the user is scrolling. In other scenarios, I may want to end the observer after a short time. This can be done using unobserve() method. It’s typically a good idea to only run the observer for as long as you need it.
What I learned
Want scrolling animations on your website?
Our team can add a solution just like this one to your media or enterprise-level website. Contact us now and let’s chat about it.