Intersection Observer
by Artem
HTML
<div class="grid-container">
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img src="https://placehold.it/960x540" /></div>
<div class="grid-item"><img...
SCSS
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-auto-rows: minmax(270px, 1fr);
max-width: 1280px;
margin: 0 auto;
}
.grid-row,
.grid-item {
display: block;
overflow: hidden;
}
.grid-item img {
object-fit: cover;
object-position: center;
width: 100%;
height: 100%;
}
.grid-item {
transform: translateY(-10%);
opacity: 0;
transition: 600ms transform cubic-bezier(0.55, 0.055, 0.675, 0.19), 600ms opacity cubic-bezier(0.55, 0.055, 0.675, 0.19) 300ms;
&.inview {
transform: translateY(0);
opacity: 1;
}
}
JavaScript
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
const rand = Math.floor(Math.random() * 30);
if (entry.isIntersecting === true) {
const img = entry.target.querySelector("img");
entry.target.classList.add("inview");
img.src = `https://source.unsplash.com/random/960x540/?${rand}`;
} else {
entry.target.classList.remove("inview");
}
});
});
const items = document.querySelectorAll(".grid-item");
items.forEach((item, index) => {
observer.observe(item, index);
});