<div class="container scroll-group--image">
<div class="text">
<h1>Simple scroll animation with IntersectionObserver API (with setTimeout delay)</h1>
<p>Scroll down past this text to see the scroll transition in action.</p>
</div>
<img class="image" src='https://images.unsplash.com/photo-1524946274118-e7680e33ccc5?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1437719417032-8595fd9e9dc6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1505738093940-b187b0e6d6d9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1453872302360-eed3c5f8ff66?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1521170813716-0b3f42fcfb65?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNzM5NQ&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1516633630673-67bbad747022?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNzM5NQ&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1524946274118-e7680e33ccc5?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
<img class="image" src='https://images.unsplash.com/photo-1437719417032-8595fd9e9dc6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyODUzNDcwMA&ixlib=rb-1.2.1&q=80&w=1200' alt=''>
</div>
.scroll {
opacity: 0;
transition: all 1s ease-out;
transform: translate3d(0, 2rem, 0);
}
.scrolled-in {
opacity: 1;
transform: translate3d(0, 0, 0);
}
/* demo styles */
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.text {
display: grid;
place-items: center;
min-height: 100vh;
width: 90%;
background: #eeeeee;
padding: 5vw;
margin: 5vw;
box-sizing: border-box;
}
img {
display: inline-block;
max-width: 25%;
height: auto;
margin: 0;
}
h1 {
font-size: 7vw;
margin: 10vw;
}
p {
font-size: 5vw;
margin: 10vw;
}
View Compiled
document.addEventListener("DOMContentLoaded", function(event) {
// get all the scroll-group elemetns.
scrollGroups = document.querySelectorAll('[class*="scroll-group"]');
// for each scroll-group element.
scrollGroups.forEach(el => {
// create an array from the element classes.
var elClasses = el.className.split ( ' ' );
// for each of the classes in the array.
for ( var index in elClasses ) {
// if the class contains the 'scroll-group-' string.
if ( elClasses[index].match ( /^scroll-group-/ ) ) {
// get the string that follows after the '--' split.
var targetClassName = elClasses[index].split ( '--' )[1];
// get the children of the element that have the target classname.
children = el.querySelectorAll('.' + targetClassName);
// for each of the children with the target classname.
children.forEach(el => {
// add the 'scroll' class.
el.classList.add("scroll");
});
break;
}
}
});
// get all of the elements with the 'scroll' class.
const scrollList = document.querySelectorAll(".scroll, [class*='scroll-group']")
const callback = (entries, observer) => {
var delay = 0;
entries.forEach((entry) => {
if (entry.isIntersecting) {
setTimeout(function () {
// add the class that triggers the animation
entry.target.classList.add("scrolled-in");
}, delay);
// increase the delay to allow a cascading effect for the elements
delay += 500; // in milliseconds
}
})
}
const options = {}
const myObserver = new IntersectionObserver(callback, options)
scrollList.forEach(scrollItem => {
myObserver.observe(scrollItem)
})
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.