Skip to main content Accessibility Feedback

How to detect when an element's visibility changes with JavaScript

Today, I wanted to show you how to detect when an element’s visibility changes using the JavaScript IntersectionObserver API. Let’s dig in!

The Use Case

I was recently working on a Web Component that calculates how much of the viewport it occupies, and automatically resizes itself to make sure it never overflows.

As a standalone component, it worked fine. But in real-world use, it was nested inside Kelp’s toggle tabs component. When it ran it’s calculations, it was inside a [hidden] parent element, and the math was all wrong.

I originally tried listening for all of the custom events emitted by Kelp components that show or hide content, but that was both error prone and not particularly sustainable.

I decided to focus on detecting when the web component’s visibility changed, and learned that you can use the IntersectionObserver API for that.

How It Works

When an element is [hidden] (or display: none, or visiblity: hidden), even if if the hidden parent is in the viewport, the element is not considered to be intersecting with the viewport.

As soon as it becomes visible, it is, and the IntersectionObserver callback method runs.

Create your observer, and run whatever callback function you need on the intersecting element (entry.target). Here, I’m running calculateSize().

const observer = new IntersectionObserver((entries) => {
	for (const entry of entries) {
		calculateSize(entry.target);
	}
});

Then, run the observe() method on the element to start checking for visibility changes.

const observer = new IntersectionObserver((entries) => {
	for (const entry of entries) {
		calculateSize(entry.target);
	}
});

const myWebComponent = document.querySelector('kelp-component');
observer.observe(myWebComponent);

That’s it!