Scroll-driven portfolio cards can fade, scale, and slide as they enter the screen without constantly processing scroll events. IntersectionObserver watches target elements and asynchronously invokes a callback when their visibility changes, while the browser performs the intersection math. section 13.3.2 section 13.4
Configure the observer around the viewport and convert visibility into CSS values:
- Set root to null to observe against the browser viewport, or specify another container; rootMargin expands the root’s calculation box. section 13.3.2
- Use thresholds from 0 through 1 to receive fine-grained visibility updates. section 13.3.2
- Read intersectionRatio: 0 means invisible and 1 means completely visible. section 13.3.2 section 13.4
- Map the ratio directly to opacity, to scale with 0.8 + ratio × 0.2, and to vertical movement with (1 − ratio) × 30. section 13.3.2
Portfolio cards that animate into view
Observe every .scroll-animate element, obtain each entry’s target and intersectionRatio, then assign opacity and a transform combining translateY and scale. Cards become more visible, larger, and higher as their visible proportion increases. section 13.3.2
Listing 13.7 Making UI changes with an intersection observer
function setupScrollAnimations() {
const options = { # #1
root: null,
rootMargin: '0px',
threshold: Array.from({ length: 101 }, (_, i) => i / 100)
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const element = entry.target;
const ratio = entry.intersectionRatio; #2
const opacity = ratio; #3
const scale = 0.8 + (ratio * 0.2); #4
const translateY = (1 - ratio) * 30; #5
element.style.opacity = opacity; #6
element.style.transform = ` #6
translateY(${translateY}px) #6
scale(${scale}) #6
`; #6
});
}, options);
document.querySelectorAll('.scroll-animate') #7
.forEach(element => { #7
observer.observe(element); #7
}); #7
} #7
setupScrollAnimations();
The listing shows the complete setup: observer options, threshold generation, entry processing, ratio-based calculations, and CSS updates. section 13.3.2
