Today, I created a fancy popup, well just a normal one, to open a overlay with a simple register form. Suddenly, someone with iPhone shouted, "Hey, that is not working on my iPhone!"
Not working? When I look at his screen, it is iPhone with Safari. Obviously, the scroll did not only scroll the popup, but also the HTML body!
Situation
I am an Android user, so I can only check with my Android phone. The popup looks fine on IE, Chrome, Firefox in desktop and Chrome/Firefox in Android.
Here the headache comes, the scroll does not work on Safari. Only Safari! Of course, you cannot reproduce this behavior on Windows or Android.
My HTML markdown is like this:
<body class="no-scroll">
<div class="overlay hide">
<div class="popup" id="popup">
<!-- Lots of contents here -->
</div>
</div>
</body>
and my CSS is like this:
.c-overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(25, 25, 25, 0.4);
transition: ease 300ms;
z-index: 1030;
}
.popup {
position: relative;
width: 100%
height: 100%;
max-width: 800px;
}
.no-scroll {
overflow: hidden !important;
}
Looks normal. Finally, after trial and errors, I know that this is exclusive behavior of Safari, or WebKit browser.
First Try: add webkit specific css
First, I tried to add this to .popup
and body:
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
It doesn't work, the body is keep scrolling! But this CSS does add momentum scrolling to my page in Safari.
Second Try: add tag on body
Some comments said they fixed it by adding this tag to body. Not working in my case. The body keeps scrolling, scrolling and scrolling.
<body class="no-scroll" ontouchstart="">
Final Answer: body-scroll-lock
I found this package from Stackoverflow, it seems to have workarounds for Safari, to stop the strange behavior while touchstart and touchmove.
Paste the minimized JavaScript tag to HTML and:
const targetElement = document.getElementById("popup"); //only popup can scroll
//put this when popup opens, to stop body scrolling
bodyScrollLock.disableBodyScroll(targetElement);
//put this when close popup and show scrollbar in body
bodyScrollLock.enableBodyScroll(targetElement);
It finally fixes my problem! Everyone is happy.
Hard to test on Safari as an Android user, but it is good to recognize this problem. Hope this guide can help someone in need. :)
Top comments (3)
If like me, you spent hours trying to find a scroll solution for Safari 10, I found it and made a simple React hooks version here: codesandbox.io/s/react-modal-scrol...
Wow, thanks for your sharing!
Works on Safari mobile, no problem.