Open basvandriel opened 4 years ago
This is intentional to offset the size of the scrollbar and prevent the page from shifting when scrolling is disabled. I'm not sure there is a way to avoid the whitespace...
I figured it's intentional. When adding the overflow: hidden
to the body the issue solves itselves.
I have a similar issue, prior to using @react-aria
I had my own prevent scroll implementation and used to disable overflow + add padding on the body element, now it's set on the root element. With fixed elements like headers the padding doesn't work obviously.
Would adding some sort of callback to usePreventcroll
be something conceivable? So that one could react and make more tweaks in sync with those changes.
https://user-images.githubusercontent.com/335467/107388355-0e56ca00-6af6-11eb-8952-f61a308e1f2c.mp4
As commented on the PR attached to this, we'll be taking a look after this sprint. @pascalduez please let us know if your app is not fixed by that proposed change
Hi @snowystinger, thanks for your feedback.
I don't think the change in #1278 is helping in my case.
Actually I have both issues: moving header content, right white space.
See a reproduction here https://codesandbox.io/s/red-violet-pm7z0?file=/src/App.js
Hey, sorry about the delay, but I'm actually unable to verify that overflow hidden on the body solves the issue as you've stated. I've done my best to reproduce it here https://codesandbox.io/s/awesome-cache-oj4g1?file=/src/App.js
@pascalduez I see your issue, you're using position fixed. Can you put a width on the parent of the position fixed (you may have to put it on some elements further up the tree as well). The end goal being to use width: inherit
on the position fixed element.
If it's possible, great! Otherwise I'm discussing other options with the team.
@pascalduez we'll need to find some other way than a callback for usePreventScroll, that'd potentially require listening to every dialog etc that makes use of usePreventScroll, in a large shared code base, this could be untenable. We don't have another idea at this time, so all ideas are welcome.
I think the best way to solve this issue is following steps
1) Instead of inline styles to html
element add custom className
compensate-for-scrollbar
2) Add this className to body
element when isActive, AND generate styles for this className
<style>
:root {
--scrollbar-width: 15px; // dynamic value generated here
}
.compensate-for-scrollbar {
padding-right: var(--scrollbar-width);
}
body.compensate-for-scrollbar {
overflow: hidden !important;
touch-action: none;
}
</style>
When is not active - nothing.
3) For fix jump for fixed elements like headers, users can use the same className on this elements to allow scrollbar-padding-fix be applied. Important note: for fullwidth fixed elements instead of width: 100%
use left: 0; right:0
to work correctly with padding compensation.
This technique is well known and used in multiple popular libraries like fancybox
.
At this moment I don't have any solution to do the same thing with usePreventScroll
as I described to achieve the same result.
I know this hook as a whole aria library is not related to styling, but I think this is a good step towards users.
I looked at the source code of the hook and came to the conclusion that, in principle, it is enough for the user that the value be placed in the style variable, then user can manually create .compensate-for-scrollbar
className with css var reference in the value.
Here is the modified code
Somewhere in your global styles
.compensate-for-scrollbar {
padding-right: var(--scrollbar-width);
}
Then
compensate-for-scrollbar
className..header.compensate-for-scrollbar:not(.is-sticky) {
padding-right: 0;
}
or just dynamically add compensate-for-scrollbar
className together with sticky
className (in case of controlled component)
That fix for me problems related with jumping fixed/sticky elements.
Regarding the issue of changing the placement of styles I don't have specific ideas why you are doing this on html
and not on the body
, but for my cases this is enough.
Any updates on this issue? It seems to still be a current thing
react-spectrum
still making progress? the best solution has already been provided above with compensation, but it's been a year
@snowystinger Hi there. Could you please kindly provide the status update on the issue, if it's not too much trouble?
@devongovett @pascalduez @basvandriel @7iomka https://github.com/adobe/react-spectrum/issues/5470#issuecomment-1969262184
same issue here, used this workaround for the DateRangePicker
<DateRangePicker
value={value}
onChange={onChange}
onOpenChange={(isOpen) => {
if (isOpen) {
document.documentElement.style.marginRight = "-15px";
} else {
document.documentElement.style.marginRight = "0px";
}
}} />
Persist scrollbar on html element (not the body) and set <ModalOverlay />
styles:
html {
overflow-block: scroll;
}
.modalOverlay {
scrollbar-gutter: stable;
position: fixed;
block-size: var(--visual-viewport-height);
inline-size: 100vw;
}
So if your fixed element header is jumping, this: pl-[calc(100vw-100%)]
should stop this (you may have to add w-[100vw] too)
For your content you also need to add 100vw and overflow-x hidden.
Demo: https://codesandbox.io/p/devbox/tmsykz?file=%2Fsrc%2Fstyles.css%3A6%2C1-6%2C5
๐ Bug Report
When the
usePreventScroll
hook is used on a non-mobile device (with a scrollbar), a strip of whitespace shows up. This happens when a element with a100%
width and height is added to the DOM.The problem is caused by the
padding-right
that's added to the html element.๐ค Expected Behavior
The whitespace should not be visible on the right side of the page.
๐ฏ Current Behavior
The
padding-right
shows up at the right side of the page.๐ Possible Solution
The body element styled should get
overflow: hidden
assigned. Also possible to give the body element the same background color as the fullscreen container, which is not optimal.๐ฆ Context
See the right side of the page, used in a new Next.js application.
๐ป Code Sample
See the Github Gist here.
๐ Your Environment
๐งข Your Company/Team
๐ท Tracking Issue (optional)