IntersectionObserver and position: absolute
Asked Answered
A

1

4

IntersectionObserver does not seem to work when the observed element has position: absolute and the root is not the viewport.

Am I missing something here?

(Try removing the position: absolute to see the expected result.)

let intersectionRoot = document.getElementById("intersectionRoot");
let observedElement = document.getElementById("observedElement");
let shifted = false; // Internal for the example

let interSectionObserver = new IntersectionObserver(
    (entries, observer) => {
        console.log(entries[0].isIntersecting)
    },
    { root: intersectionRoot }
);
interSectionObserver.observe(observedElement);

window.setInterval(
    () => {
        observedElement.classList.toggle("shifted")
    },
    1000
)
#intersectionRoot {
    background-color: red;
    width: 100px;
    height: 100px;
}

#observedElement {
    position: absolute;
    background-color: green;
    width: 50px;
    height: 50px;
}

.shifted {
    transform: translate3d(110px, 0, 0)
}
<div id="intersectionRoot">
    <div id="observedElement" draggable="true"></div>
</div>
Andreas answered 15/1, 2021 at 12:46 Comment(4)
Sorry if i'm missing something, what if you add position: relative to #intersectionRoot ? Is that the expected behavior? demoMader
Yeah that seems to do it. Is there a reasonable explanation for why IntersectionObserver would work like this?Andreas
I guess it's because if you don't explicitly set position: relative to the root element its children (in this case observedElement) refers to the body. From the docs: An IntersectionObserver with a non-null root is referred to as an explicit root observer, and it can observe any target Element that is a descendant of the root in the containing block chain.Mader
Ohh that's tricky. It would be alot easier to understand if the visual intersection was what mattered. Thanks anyway, if you post it as an answer I'll accept it.Andreas
M
4

The solution is to add position: relative to the root element. Here's an updated demo.

If you don't explicitly set position: relative to the root element its children (in this case observedElement) refers to the body. From the IntersectionObserver docs: An IntersectionObserver with a non-null root is referred to as an explicit root observer, and it can observe any target Element that is a descendant of the root in the containing block chain.

Mader answered 15/1, 2021 at 14:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.