Skip to content

scroll-padding not respected when ListBox is rendered in a Popover #7037

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jeffijoe opened this issue Sep 14, 2024 · 10 comments · Fixed by #7484
Closed

scroll-padding not respected when ListBox is rendered in a Popover #7037

jeffijoe opened this issue Sep 14, 2024 · 10 comments · Fixed by #7484

Comments

@jeffijoe
Copy link
Contributor

jeffijoe commented Sep 14, 2024

Provide a general summary of the issue here

When a ListBox which contains scroll-padding styles is rendered in a Popover, the scroll padding is not respected. For example, the contact list example uses and shows the usefulness of scroll padding, but if that contact list was to be rendered in a popover, it would result in a bad keyboard experience as the focused item may be obscured by a sticky header.

🤔 Expected Behavior?

Scroll padding should work regardless of whether the listbox is rendered in a popover.

😯 Current Behavior

The scroll padding during keyboard navigation is not respected, resulting in any sticky headers clipping the focused item.

The following video is from the code sandbox reproduction:

listbox-issue-encoded.mp4

💁 Possible Solution

I thought it was a general browser issue with scroll padding and having the scroll container hosted in a non-static container. I tried placing it in a simple div with position: absolute|fixed but the issue did not reproduce. It was only inside the popover I could reproduce it.

🔦 Context

My use case is a Select with sticky headers:

image

🖥️ Steps to Reproduce

See this code sandbox which includes both a reproduction and an option to render the list box outside a popover to observe that it works correctly otherwise.

Version

RAC 1.3.3, RA 3.34.3

What browsers are you seeing the problem on?

Chrome, Safari

If other, please specify.

No response

What operating system are you using?

macOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

@snowystinger
Copy link
Member

@LFDanLu I think you've been looking at some scroll-padding issues in Table. Anything related to your findings here?

@LFDanLu
Copy link
Member

LFDanLu commented Sep 16, 2024

https://issues.chromium.org/issues/365913982 which came from that Table investigation definitely shows up as an issue for when the ListBox isn't rendered in a Popover, but I'm not sure that is the reason for the "in popover" behavior that is being exhibited here since increases to the scroll-padding doesn't seem to affect the positioning at all still.

@jcorkhill
Copy link

I see the same erroneous behavior in Firefox Developer Edition 131.0b7 (aarch64).

@deebov
Copy link
Contributor

deebov commented Sep 21, 2024

We're having the issue too. Has anyone found a good workaround for this yet?

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Oct 3, 2024

I noticed scroll padding isn't working for us inside scrollable dialogs as well, perhaps related to #7131 - when focus moves around, the scroll padding I defined on the scroll container is not respected.

@jeffijoe
Copy link
Contributor Author

In case it's helpful to the maintainers: I upgraded the packages in the sandbox to the latest released versions (3.36.3 and 1.5) and the issue persists.

@devongovett
Copy link
Member

My guess is this:

let isScrollPrevented = window.getComputedStyle(root).overflow === 'hidden';
// If scrolling is not currently prevented then we aren’t in a overlay nor is a overlay open, just use element.scrollIntoView to bring the element into view
if (!isScrollPrevented) {

If scroll locking is enabled, this alternate path is used:

let scrollParents = getScrollParents(targetElement);
// If scrolling is prevented, we don't want to scroll the body since it might move the overlay partially offscreen and the user can't scroll it back into view.
for (let scrollParent of scrollParents) {
scrollIntoView(scrollParent as HTMLElement, targetElement as HTMLElement);
}

scrollIntoView is a custom implementation that we use to avoid scrolling the body while a modal/popover is open. Unfortunately the native scrollIntoView doesn't support that (see w3c/csswg-drafts#9452). So I guess we would need to adjust the calculation in that function to take scrollPadding into account.

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Dec 5, 2024

Ah interesting! I didn't know about the alternative path for scrolling - checking for scroll padding there seems like it would do the trick.

If it's as simple as reading the scroll padding here and adding it, then I could take a stab at it?

@devongovett
Copy link
Member

Sure, that'd be great

jeffijoe added a commit to jeffijoe/react-spectrum that referenced this issue Dec 5, 2024
@jeffijoe
Copy link
Contributor Author

jeffijoe commented Dec 5, 2024

@devongovett I've opened PR #7484 with a fix, thanks for pointing me in the right direction.

jeffijoe added a commit to jeffijoe/react-spectrum that referenced this issue Dec 5, 2024
jeffijoe added a commit to jeffijoe/react-spectrum that referenced this issue Dec 5, 2024
jeffijoe added a commit to jeffijoe/react-spectrum that referenced this issue Dec 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants