An element can intersect the viewport while nobody is looking at it. That sounds obvious until a dashboard labels every intersection as a view. IntersectionObserver is useful, but its ordinary observation is a geometric signal, not a measurement of attention.
The observer compares a target element with a root. With a null root, it uses the implicit root associated with the top-level viewport. You can instead specify an appropriate ancestor as the root, such as a scrolling panel. The root matters: an item can intersect a panel without the panel itself being on screen.
The intersection ratio describes the area of the intersection rectangle relative to the target’s bounding rectangle, when the target has nonzero area. Ancestor clipping can reduce the intersection. Thresholds tell the observer which ratios matter to your application; a threshold of 0.5 is useful when you want an update around the halfway point.
For example, a page might prepare a chart when at least half of its placeholder intersects the viewport:
<div id="chart-placeholder">Chart loading area</div>
<script>
const target = document.querySelector('#chart-placeholder');
const observer = new IntersectionObserver((entries, obs) => {
for (const entry of entries) {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
entry.target.textContent = 'Ready to prepare the chart';
obs.unobserve(entry.target);
}
}
}, { root: null, threshold: 0.5 });
observer.observe(target);
</script>
The observer also provides an initial observation, so the callback checks the ratio rather than assuming every callback means the threshold was reached. Unobserving after the first qualifying entry makes this a one-time preparation trigger. A real chart loader should handle loading failure and provide an appropriate fallback.
Entries are delivered asynchronously and describe recorded moments, not a continuous stream of exact pixel changes. The API’s geometry also has edge cases: touching the root boundary can count as intersecting even when the intersection has zero area. For a zero-area target, the ratio has special rules, so avoid interpreting it as a literal percentage of visible pixels.
The ordinary calculation does not establish that the target is unobscured by another element, that the tab is foregrounded, or that a person read it. A positive root margin can even trigger before the target reaches the viewport. Optional visibility tracking can consider some visual compromises, but it is more expensive, can be conservative, and does not measure human attention either.
Use intersection to schedule work or describe geometric exposure with a precise label. If you need a stronger metric, define its limitations and additional conditions explicitly. Do not turn a rectangle crossing a threshold into a claim that someone saw the content.

The Campfire
CommentsThanks. Your comment is waiting for the desk. Once it is approved it appears here within about a minute.
Add a comment