Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS Safari: unwanted scroll when keyboard is opened and body scroll is disabled

Tags:

html

css

ios

There is a known technique to disable page scroll when modal window is opened.

CSS:

html {
  height: 100%;
}

body.disable-scroll {
  position: fixed;
  height: 100%;
  overflow: hidden;
}

HTML:

<!DOCTYPE html>
<html>

<head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport">
</head>

<body class="disable-scroll">
    <div class="page-content">
        <input type="text">
        ... content ...
    </div>
</body>

</html>

But on IOS Safari scroll becomes enabled after virtual keyboard is opened. And it scrolls more than even window.innerHeight + window.scrollX. Some blank gap appears at bottom of the page. enter image description here

Editor's url
https://codesandbox.io/s/condescending-snow-skuo5?fontsize=14

Fullscreen url to check on IPhone
https://skuo5.codesandbox.io/
Just open on IPhone or in XCode with IOS 12+ try to scroll and then focus on Input and try to scroll again.

like image 270
Dzmitry Vasilevsky Avatar asked May 28 '19 23:05

Dzmitry Vasilevsky


2 Answers

Just went through tedious searching and seems that's an issue with iPhone as you have pointed in following article : https://blog.opendigerati.com/the-eccentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d

So there is no way you can do it with css for sure.

But that doesn't stops you from using JQuery and Javascript >:)

Here is an untidy work around for your scenario. Have tested with multiple text boxes too on iPhone only:

document.getElementById("app").innerHTML = `
<div class="page-content">
<input type="text" 
onfocus="disableScrolling(this)" 
onfocusout="enableScrolling(this)">
  <p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p>
  <input type="text" 
  id="text2"
onfocus="disableScrolling(this)" 
onfocusout="enableScrolling(this)">
  <p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p>
</div>`;

var currentElem;	

function stopScroll() 
{
    if(currentElem)
    {
        var top = $("input:focus").offset().top;
        $('html, body').stop().animate({
            scrollTop: top
        }, 500, function(){});
    }
}

function disableScrolling(elem) 
{
    currentElem = elem;
    document.addEventListener("touchend", stopScroll);
    setTimeout(function()
    {
        stopScroll();
    },10);
}

function enableScrolling() 
{
    currentElem = undefined;
    document.removeEventListener("touchend", stopScroll);
}
html {
  height: 100%;
  scroll-behavior: smooth;
}

body.disable-scroll {
  position: fixed;
  height: 100%;
  overflow: hidden;
}

.page-content {
  background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="disable-scroll">
  <div id="app"></div>
  <div>End of body</div>
</body>
To explain in short what I did.

Problem : User can scroll away while focusing on textbox

Assuming that,

Solution : Allow user to scroll where ever he want and once he is done bring him back smoothly to where you want him to be; input:focused :p

Note : I have used JQuery to make things simpler. If you want to use pure javascript, you can find the replacement for the specific codes.

like image 119
Prajyot Tote Avatar answered Sep 18 '22 11:09

Prajyot Tote


Just some info for anyone arriving here.

Safari thinks this is feature. There is a bug report here (let them know you don't like this "feature" =]).

When you open the keyboard, the browser's window is moved up and your content is hidden because the window is out of the screen. Other weird behaviors can happen too, like the one the OP showed.

Scrolling out of the screen

Check this blog post for more details and more examples of weird behaviors (I copied the image above from it): https://blog.opendigerati.com/the-eccentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d

like image 28
jpenna Avatar answered Sep 20 '22 11:09

jpenna