svelte-simple-modal icon indicating copy to clipboard operation
svelte-simple-modal copied to clipboard

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

Open trancephorm opened this issue 3 years ago • 8 comments

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

trancephorm avatar Dec 19 '21 21:12 trancephorm

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.

flekschas avatar Dec 20 '21 08:12 flekschas

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 avatar Jan 28 '22 14:01 ohnv

I tried the following within the repl:

  • Aligned all buttons to the right (so that the scroll bar naturally displaces them)
  • Added the following line to the disableScroll function: document.body.style.paddingRight = '25px'; plus corresponding line in the enableScroll function.

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)

ohnv avatar Jan 28 '22 15:01 ohnv

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).

flekschas avatar Jan 28 '22 20:01 flekschas

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

  • Disable the pointer events on body (document.body.style.pointerEvents = 'none';) so it becomes impossible to interact with the scrollbar and scroll the content.
  • Enable them back on the background element to regain interactivity on the modal background and its descendants (the modal itself).

nltesown avatar Apr 18 '23 13:04 nltesown

@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.

flekschas avatar May 05 '23 22:05 flekschas

@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...

nltesown avatar May 24 '23 09:05 nltesown

@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.

flekschas avatar Jul 01 '23 18:07 flekschas