Configuring when an element counts as visible
IntersectionObserver watches when target elements enter or leave a root
viewport and reports it asynchronously, replacing janky scroll listeners. Its
behaviour is shaped by three constructor options and read through the
IntersectionObserverEntry passed to your callback. This reference documents
both, with a live validator for the tricky rootMargin string.
How it works
You create an observer with options, then observe one or more targets:
const io = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
if (entry.isIntersecting) loadImage(entry.target);
}
},
{ root: null, rootMargin: "0px 0px -100px 0px", threshold: [0, 0.5, 1] }
);
io.observe(document.querySelector(".lazy"));
root defines the viewport (the browser viewport when null). rootMargin
expands or contracts that box — a negative bottom margin makes the callback fire
only once the target is well inside view. threshold lists the visibility ratios
that trigger the callback, so you can react at 0%, 50% and 100% visibility.
Tips and notes
rootMarginusespxor%only — never bare numbers or other units.- Pass a
thresholdarray to animate smoothly as an element scrolls through view. - Read
intersectionRatiofor how much is visible andboundingClientRectfor where it sits. - Call
io.unobserve(target)after a one-shot trigger (like lazy-load) to stop further callbacks.