emilkowalski / vaul

An unstyled drawer component for React.
https://vaul.emilkowal.ski
MIT License
6k stars 201 forks source link

Radix dialog --removed-body-scroll-bar-size variable set to 0 #285

Closed arekrgw closed 2 weeks ago

arekrgw commented 7 months ago

When opening normal radix dialog, css variable --removed-body-scroll-bar-size on body element is set to some pixel value that represents the scrollbar width when it hides. That's not the case with this lib Drawer, variable is set to 0px all the time, creating content shift on the page

To reproduce you need to have to have some content on the page and then open the right/left drawer.

After some investigation it looks like the css position override to fixed from relative on body element is the issue.

image

dschlabach commented 6 months ago

As a temporary workaround for those of us using a right-aligned drawer, you can do this:

body[data-scroll-locked] {
  padding-right: 15px !important;
}

Edit: only works though if the page has a scrollbar. If not, it'll push everything over 15px :/

emilkowalski commented 6 months ago

Cam you provide a demo with reproduction?

dschlabach commented 6 months ago

Hey! I've created a reproduction highlighting the issue here:

https://stackblitz.com/edit/nextjs-nqthme

hamishtaplin commented 6 months ago

Also experiencing this having to come to this from using shadcn

voyageur-design commented 5 months ago

Also Experiencing this when using right or left aligned drawers

Andrii-Antoniuk commented 4 months ago

This is still an issue in 0.9.1. The issue is that both html and body tags receive padding-right and margin-right, respectively. I don't see any references to such styles in the repo, so is this coming from Radix/some dep? 🤷 The workaround would be to set !important on either html or body (can't do on body since there it is with !important too) with styles.

New reproduction link (with 0.9.1) - https://stackblitz.com/edit/nextjs-j6eglw?file=app%2FDrawer.tsx @emilkowalski FYI

HarleySalas commented 3 months ago

don't see any references to such styles in the repo, so is this coming from Radix/some dep? 🤷

It must be something in vaul, as when you use the radix library alone, there are no such issues with the scrollbar.

Andrii-Antoniuk commented 3 months ago

It must be something in vaul, as when you use the radix library alone, there are no such issues with the scrollbar.

Simple CTRL+F didn't find anything 🤔 Could it be that it was a bug in radix before, but now in latest version they have fixed it?

erip2 commented 2 months ago

I investigated this problem further because as others have mentioned here, this problem doesn't occur on the radix dialog component.

I tried to see how the react-remove-scroll-bar library was running behind the scenes. It is this library that sets the --removed-body-scroll-bar-size. To be more specific, it's the getGapWidth function inside utils.js.

The components difference is on document.documentElement.clientWidth value. On the Radix Dialog component, this value is correct, but on the Drawer one is the same as window.innerWidth which causes the value of the gap to be always 0.

The reason for these values to be the same is that vaul adds classes to the body which affect the clientWidth value.

Then I figured to add the noBodyProps prop, but the flickering problem remained. I found out another difference between the component, and that it was a class in <html>, a padding-right that was added when using the vaul component.

This padding was also added by vaul. Easy to remove though, by another prop: disablePreventScroll.

So, by adding both of these props, you can remove the flicker effect when opening the drawer on the right (or left).

--

Anyway, I am not sure of the other effects of these props, as they may break other functionalities in some cases, but at the moment, this is a fine solution for me.

sunwrobert commented 3 weeks ago

Yup, setting disablePreventScroll and noBodyStyles fixes the issue

emilkowalski commented 2 weeks ago

This has been fixed now, the --removed-body-scroll-bar-size CSS variable should now set the correct value automatically.