No Prequisites
The code below does not require any libraries or frameworks. It is just plain HTML, CSS, and JavaScript. So for this effect, I am using the browser’s built-in Intersection Observer API. Nothing else.
How It Works
The JavaScript code below will add opacity-0 class to all elements with the observe class which are not in the view right now. Then it is passively waiting for the element to be 25% in view. When that happens, it will remove the opacity-0 class and add the animate-slide-in class to the element. This will trigger the CSS animation.
Unserstanding threshold and rootMargin
When working with the Intersection Observer API, you will come across two important properties: threshold and rootMargin. Here is a nice interactive resource to understand these properties better: Intersection Observer Playground
HTML
For this effect to work, all we need to do is to add the observe class to the element where we want this effect to happen.
<div class="observe">
This should fade in when 25% of
this element is in view,
creating a nice fade in effect.
</div>Of course you will also need to add the CSS and JavaScript below for this magic to work.
CSS
I am using Tailwind but if you don’t use it, here is the CSS you will need for this effect:
@keyframes slide-in {
0% {
transform-origin: top;
transform: scale(0.8);
opacity: 0;
}
100% {
transform: scale(1);
transform: translateY(0);
opacity: 1;
}
}
.animate-slide-in {
animation: slide-in 0.5s ease-out;
}
.opacity-0 {
opacity: 0;
}JavaScript
At first we will create an observer and then call .observe(section) on all elements with the observe class.
const callback = (observerEntries) => {
observerEntries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.remove('opacity-0');
entry.target.classList.add('animate-slide-in');
} else {
entry.target.classList.add('opacity-0');
}
});
}
const options = {
rootMargin: '-0% 0% -25% 0%'
};
const observer =
new IntersectionObserver(callback, options);
document
.querySelectorAll('.observe')
.forEach((section) => {
observer.observe(section);
});Warning
If an element is not at least 25% in the view it will stay invisible.