kaisdukes / quranic-corpus

The Quranic Arabic Corpus, an invaluable linguistic resource, is due for a revamp. We're calling on Linguistics, AI, and Tech volunteers to join us in this exciting journey. 🚀
https://qurancorpus.app
GNU General Public License v3.0
80 stars 8 forks source link

Bug: main area scrolls when popup is open on mobile. #63

Open kaisdukes opened 1 year ago

kaisdukes commented 1 year ago

To test any fix for this bug you will need access to an iPhone (or an iPhone emulator). One fix to this problem is to add the following effect to the workspace:

useEffect(() => {
    if (focusMode && info) {
        document.body.classList.add('no-scroll-mobile');
    } else {
        document.body.classList.remove('no-scroll-mobile');
    }
}, [focusMode, info]);
body {
    @media only screen and (max-width: 599px) {
        &.no-scroll-mobile {
            overflow: hidden;
        }
    }
}

This works on most browsers, e.g. on a small browser window with width < 600px this works on Safari desktop. However, this doesn't seem to work on iPhone. The issue may be related to an ongoing issue with iOS Safari. Safari on iOS doesn't seem to respect the overflow: hidden CSS property on the body tag as other browsers do.

This issue happens because on iOS Safari, the overflow property doesn't prevent scroll on the body element itself. Instead, it creates a new stacking context, so position: fixed elements are fixed according to the overflowing container, not the body.

mustafa0x commented 1 year ago

I use touch-action: none; on the modal backdrop. Might apply here.

Also, classList.toggle(className, state) to shorten code.

kaisdukes commented 1 year ago

Thanks bro! That's really useful. Preventing the touchmove event might also work...

useEffect(() => {
    const preventBodyScroll = (event) => {
        event.preventDefault();
    };

    if (focusMode && info) {
        document.body.addEventListener('touchmove', preventBodyScroll, { passive: false });
    } else {
        document.body.removeEventListener('touchmove', preventBodyScroll);
    }

    return () => {
        document.body.removeEventListener('touchmove', preventBodyScroll);
    };
}, [focusMode, info]);