Happy holiday folks! All the best from us at Digitpaint

Day 22

Acting on element visibility with Intersection Observer


The Intersection Observer API makes observing the user's viewport a lot easier. It can be used to make some interesting things happen. For example; it enables you to easily lazy load parts of your website, trigger animations or add different styling on elements as you scroll past certain points. It's also very useful for creating a legend which then indicates at what paragraph you are looking.

Demo time

The demo works in most browsers, but it is not supported in Safari.

Let's change this color

It is also possible to check how much of an element is visible. If more than 50% of this element is visible, the background-color will be set to green. We gave the threshold property a value of 0.5, so the observer will only get called when the element is only semi-visible.

Watch the navigation!

The sticky navigation you already know from yesterday's demo is back, but it now gets its padding decreased when the header is not visible to the user. On every change, the called method observes whether the viewport is intersecting with the header or not.


I start animating when my parent is in view

You can also use IntersectionObserver for animating elements or even create new elements (lazy loading).

How does it work?

First of all, start off by creating a new IntersectionObserver object. The object requires the action it should take as the first parameter. The second parameter is optional. Options like the threshold, the root and the rootmargin are defined here. The threshold sets the position on which the coupled action is going to be performed. When the threshold is set to 0.50 for example; the observer will trigger the action when half of the element that's being observed is visible. root can be used to define an element to use as a viewport. This has to be an ancestor of the element that's being observed. Default is the browser's viewport. The rootmargin creates an offset which the observer takes in account when calculating the intersection points.

        let observer = new IntersectionObserver(onChange, {
          threshold: [ 0.50 ],
          rootMargin: '50px'

In the code above, we tell the API to observe a specific element. This observer will call the onChange function when 50% of the element resides inside of the viewport, minus the 50px specified in rootMargin.


When the page-header element's visibility passes the 50% mark, as defined in the first code snippet, the onChange function is called, in which we can perform all kinds of magic.

          function onChange(changes) {
            changes.forEach(change => {

Browser compatibility

Browser compatibility is pretty solid. The API is supported by most major browsers.

  • Chrome
  • Edge
  • FireFox
  • Samsung Internet
  • Chrome for Android

more detailed information on caniuse.com


Demo source code

Do you want to dig in the nitty-gritty of this demo, check out the source files:

Back to home