The browser now does what your scroll listener did.
The common read: positioning one box against another is geometry the platform does not do for you, so the numbers have to come from getBoundingClientRect and be written back every frame.
Making that decision at every scroll step was the listener's job: read where the trigger is, decide which side the tooltip fits on, write the numbers back, and repeat when anything moves. Two CSS properties now declare the relationship instead. anchor-name marks the trigger as an anchor under a name you choose, and position-anchor on the tooltip says which named anchor it is positioned against. From there, anchor() reads the anchor's edges into inset properties and position-area places the tooltip in one of the nine regions around it.
Chromium, Firefox and WebKit all ship anchor positioning. During the rollout the three engines disagreed about what an unset position-anchor resolves to, which is why every listing in this lesson writes it out. The listener was the correct approach, because a stylesheet had no way to say "under that element". Everything added to it after the first version (the scroll and resize handlers, the frame throttle, the flip logic for the last row, the teardown) worked around that missing feature.
Takeaway: The listener ran on every scroll frame to redo arithmetic the browser can now do in layout.
The cost is small. You can no longer read the position back out of an inline style attribute, which is what your integration tests asserted on, and you no longer have the number to use in your own code. In exchange, the tooltip stays in the right place during a scroll your code never listens to.

