flekschas / svelte-simple-modal

A simple, small, and content-agnostic modal for Svelte v3 and v4
https://svelte.dev/repl/b95ce66b0ef34064a34afc5c0249f313
MIT License
422 stars 31 forks source link

Is there a way to disable hiding of document scrollbar in the background when modal is loaded? #59

Open trancephorm opened 2 years ago

trancephorm commented 2 years ago

It's kind of ugly watching the whole content behind moves to the right because scrollbar gets hidden when modal is shown.

flekschas commented 2 years ago

If you know a solution how to not hide the scrollbar and still avoid scrolling of the content in the background on desktop and mobile devices, then I am super happy to merge your PR or implement it. However, I don't know how to keep the scrollbar and avoid scrolling on iOS.

For context see #28.

ohnv commented 2 years ago

I noticed that the linked article in #28 mentioned simply putting

 padding-right: 15px; /* Avoid width reflow */

on the body element. Taking a quick look at Model.svelte I don't see an equivalent (I haven't run this personally or pulled the repo so apologies if I am completely off base). Don't suppose it's that simple to avoid the (majority) of the jank??

  const disableScroll = () => {
    scrollY = window.scrollY;
    prevBodyPosition = document.body.style.position;
    prevBodyOverflow = document.body.style.overflow;
    prevBodyWidth = document.body.style.width;
    document.body.style.position = 'fixed';
    document.body.style.top = `-${scrollY}px`;
    document.body.style.overflow = 'hidden';
    document.body.style.width = '100%';
  };
ohnv commented 2 years ago

I tried the following within the repl:

This resulted in the buttons retaining their exact position when tested on Firefox.

Obviously in real life there is more to think about (different browsers = different scroll bar widths?) but for certain scenarios this could be a way to avoid the background moving about.

(Edit: Sorry, I just realized this issue was more pertaining to the scroll bar itself hiding, but the initial posters reason for frustration was "It's kind of ugly watching the whole content behind moves to the right" - so I hope these comments are ok to stay here)

flekschas commented 2 years ago

Thanks for taking a stab at it. I believe that this works in some situations. However, the problem is that different operating systems and browsers might have different scrollbar widths. And then there are situation where the browser doesn't even display a scroll bar (like on macOS when no external mouse is connected).

nltesown commented 1 year ago

Instead of hiding the scrollbar, it may be possible to:

flekschas commented 1 year ago

@nltesown Interesting suggestion! Do you know if this is a tested approach? I'm open to change the implementation but I want to make sure it works properly on the majority of browsers.

nltesown commented 1 year ago

@flekschas Unfortunately, I don't know. The pointerEvents property is very widely supported and I'm not aware of possible issues. It looks safe enough.

Here's why I think this is a problem worth addressing: the projecty I'm currently working on displays a full-width calendar (7 columns, many rows), with each cell possibly having text wrapped on several lines. Therefore the disappearance of the scrollbar when the modal opens is almost certain to affect the table's layout in a very heavy and ugly way – each columns gets some extra width, allowing the cells' text content to reflow, which in turn may alter row heights...

flekschas commented 1 year ago

@nltesown I've tested the pointer-events only approach but it doesn't work. My guess is that the WheelEvent (which is not a PointerEvent) is not disabled.

Here's an example demo: https://svelte.dev/repl/b63bc130e4474fe384373bd01391796a?version=4.0.1

Feel free to play around with the demo and let me know if I missed something.