Repository navigation
Scroll into view with sticky elements and page scrolling can cause bad-large jumps #10182
Description
Activity
alternative solution we think would be to go to nearest rather than center..
related and possibly fixed by (maybe?!) - https://github.com/adobe/react-spectrum/pull/9780/changes
reproduced this locally, it isn't fixed by #9780 unfortunately (which was released as a part of 1.18). Ideally instead of doing the scrollIntoView center we'd have similar behavior to scrollIntoViewIfNeeded. I don't think skipping the target element's scroll container's scroll into view is quite right since the container itself still could be out of view (e.g. an scrollable overlay with a really large table that is out of view or something), but
nearestdoesn't quite to be quite right when I test locally (it is definitely an improvement over thecentercase here but causes large jumps when navigating to a row that is out of view)@LFDanLu Will be addressed by the coming refactor, once I find the time to wrap the work up. It will always use our shim, which implements scrollIntoViewIfNeeded - similarly btw, I noticed that the subpixel hack makes no sense at all for the shim, since again, it implements if needed behavior already 🤣
Reacted by Daniel Lunice, thanks for looking into it!
- marked Incorrect offset calculation for elements positioned with transform: translate() in scrollIntoView #7716 as a duplicate of this issue
on Aug 12, 2026 @LFDanLu Okay, I'm very close to having the necessary utils in place to fix this properly. One thing that is still not quite clear to me is what
scrollIntoViewports centering is actually built for. I know it is passed the collections scroll ref as the containing element, but that doesn't explain to me why we are trying to center instead of using nearest for example. Was there a specific interaction problem?If we assumed a perfect Web API, without sub-pixel hacks, a working if-needed, and awaitable scroll sequences, then what would this be trying to do? I will try and dig up the information, but also figured asking is cheaper 😅
@nwidynski from what I recall, the "centering" behavior was for a case like the following:
Imagine a user has keyboard focus on an element in a table that is both scrolled out of view w/ respect to the table's body and is also out of view of the visual viewport. If the user keyboard navigates to another cell, ideally the whole table (or a good chunk at least) should be brought into view alongside scrolling the table body such that the newly focused cell is in view. Centering the "containing element" in this case to to provide the user with enough visual context of what their interaction is currently affecting.Quite the edge case honestly and I'm not convinced its worth keeping it tbh, and I don't recall if there any other cases that this helped handle. Thanks for continuing to look at this!
@LFDanLu Okay, that's what I figured, but why 'center' specifically? Nearest would also have brought the whole table into view, right? I'm asking because nearest is special case'd in the spec to do nothing when the element is larger than its scrollport, which start/center/end is not, so really the jump to the center is doing what its supposed to.
I know you've tried to set nearest previously, and that also caused jumps, but that one is fixable. The other one really kinda isn't, and we would have to test for size to dynamically switch between nearest and center or something to make that work.
@nwidynski I could've sworn that using "nearest" used to only bring in a sliver of the table into view, but maybe behavior has changed since I last worked on that (I believe this was back in the v3 TableView days haha). We can roll with "nearest" for now and I'll get the team to do some testing cross browser
@LFDanLu Do you happen to remember which story or docs example jumped when changing to 'nearest'? Just want to make sure we are looking at the same thing, since I cant replicate it upon first try.
PS: Are you talking about the jump the table makes upon navigating to the first row thats out of view? If so, then I think that would come expected as the table is aligned 'nearest', which resolves to its 'start' edge in this case. Thereby we "jump", because of 'instant' behavior, as the table is aligned with the start edge of the viewport.
@nwidynski for the "jumping" reproduction I believe was just using the issue's sandbox configuration locally in the storybook if I remember correctly. Also just to illustrate the "center" vs "nearest" I tried this again locally as well.
Screen.Recording.2026-08-13.at.4.47.54.PM.mov
Screen.Recording.2026-08-13.at.4.48.41.PM.mov
The first is with "nearest" and the second is with "center" (aka current behavior), using https://reactspectrum.blob.core.windows.net/reactspectrum/ffc882581a109848b56db67381fc8a3a1b9b4c21/storybook/index.html?path=/story/tableview--dynamic&providerSwitcher-express=false and modifying
containingElement?.scrollIntoView?.({block: 'center', inline: 'center'}); I am actually fine with the "nearest" behavior here tbh, but I do feel like moving the table to the center of the screen feels better from a user perspective IMO.
for the "jumping" reproduction I believe was just using the issue's sandbox configuration locally in the storybook if I remember correctly.
@LFDanLu Haha, alright, then we are looking at the same 👍 I believe what you identified as a jump was just the nearest behavior kicking in and looking unfamiliar then. I agree that 'center' has a better UX, but really the only way to keep supporting that is to conditionally switch between 'nearest' and 'center' depending on whether the containingElement is larger than its nearest scrollParent. From my exploration, that would be a rather large effort, because scroll prevention is currently coupled to querying scroll parents.
PS: Out of interest, have you guys made any decision yet as far as floating-ui is concerned? I saw there is a ticket looking to replace the overlay positioning code. I've been working on an alternative for react-aria's use case, based on CSS anchor positioning, that's a lot smaller than floating-ui, which I think could fit perfectly.
@nwidynski yeah I don't think its worth the extra complexity for now, we can test it out and the team can weigh in. As for floating-ui, we have been hesitant to pull it in due to bundle side increase + relying on a external dependency so def would prefer a in repo solution haha
Provide a general summary of the issue here
We have a table with the scrolling element above the table (now supported by your virtualizer, thanks!) and some sticky elements.
changing the focussed row down and up works, but when you press up going from the top table row to the table header, the page jumps and focus is now out of view.
🤔 Expected Behavior?
no significant jump when moving through rows
😯 Current Behavior
a big jump moving from the top table row to the table header.
💁 Possible Solution
Take this with a pinch of salt - this is what AI generated as a fix - it appears to work though:
🔦 Context
We have this situation in our app with a table and some sticky elements, so keyboard support for the table appears broken and inaccessible.
🖥️ Steps to Reproduce
Go here:
https://codesandbox.io/p/sandbox/gwl9xx
or manually:
Version
1.18.0
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
windows
🧢 Your Company/Team
Saxo Bank
🕷 Tracking Issue
No response