Zero Sized Intersection Observers

AuthorTaylor Hogge
Apr 06, 2024

The IntersectionObserver spec is ambiguous in it's treatment of zero-sized elements. This results in inconsistent behavior across platforms. Developers should avoid observing zero-sized elements using the IntersectionObserver API.

A common solution to implement infinite-scroll is to place a marker element at the end of a scroll container. That element is observed using the IntersectionObserver API. When the observed element scrolls into view, you know you are at the bottom of the scroll container and you can fetch the next page of data.

<ul>
  <li>One</li>
  <li>Two</li>
  ...
  <li>Fifty</li>
  <div id="loadMore"></div>
</ul>

As is, this layout does not work across platforms. The IntersectionObserver spec states that the threshold value is used to configure what percentage of the observed element must be visible before triggering the callback. So what happens if the target element has zero size? To compute this percentage you would have to divide by zero. The spec is clear that a threshold of zero is effectively "any non-zero number of pixels". However, it makes no comment on how zero-sized elements should be handled. One could make the argument that the empty element is fully contained by the viewport once visible and should count as an intersection.

The w3c added the isIntersecting flag partially for this purpose but never disambiguated how zero-sized elements should interact with the threshold value in order to trigger the observer callback. Because of this, there is platform-dependent behavior with this edge case.

As written, the code above will trigger the observer callback on MacOS (Firefox and Chrome) but not on Windows (Chrome). In order to ensure consistent behavior across platforms, developers should always add some content to elements observed by the IntersectionObserver API.

<ul>
  <li>One</li>
  <li>Two</li>
  ...
  <li>Fifty</li>
  <div id="loadMore" style="visibility: hidden">LOAD MORE</div>
</ul>