Description
Describe the bug
I use useWindowVirtualizer hook for making virtual elements and scrollToIndex with dynamically-sized elements and { align: "start" }.
After scrolling the page manually (to allow the virtualizer to cache element heights), clicking the “Scroll to element” button scrolls correctly to the element’s header. However, after that, scrolling becomes impossible — the page keeps snapping back to the element’s header, effectively locking the scroll.
Note: I found a similar issue #473
Your minimal, reproducible example
https://codesandbox.io/p/devbox/heuristic-rgb-qwt484?file=%2Fsrc%2Fmain.tsx%3A34%2C16
Steps to reproduce
Zoom the page in Safari (e.g., 120%).
Scroll to an element with index 70.
Press the "scroll to element" button.
Try to scroll normally.
Expected behavior
After scrolling to the element, the user should be able to scroll the page freely.
How often does this bug happen?
Every time
Screenshots or Videos
Screen.Recording.2025-04-10.at.16.29.35.mp4
Platform
I reproduced it in
Safari - 15.6.1, 18.2, 18.3.1
tanstack-virtual version
3.13.6
TypeScript version
No response
Additional context
This issue seems to happen when the page is zoomed in Safari. Safari can render line-wrapped text elements with fractional heights, which may cause inconsistencies in the virtualizer’s height calculations and result in incorrect scroll positioning or locking.
This code is triggered in an infinite loop because accumulated height inaccuracies cause a mismatch with the initialOffset (window.scrollY) value. I'd expected to break this loop if it made more than N calls with the same values.
Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.