Scrolling issue occurs on IOS Safari when the keyboard is opened, despite having disabled body scroll feature

Have you ever tried to disable page scroll when a modal window is opened?

CSS:

html {
  height: 100%;
}

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

HTML:

<!DOCTYPE html>
<html>

<head>
    <title>Unique 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">
        ... more unique content ...
    </div>
</body>

</html>

However, on IOS Safari, the scroll becomes enabled after the virtual keyboard is opened. It scrolls even more than

window.innerHeight + window.scrollX
, creating a blank gap at the bottom of the page. https://i.sstatic.net/X7Vy3.jpg

Check out the editor's URL here: https://codesandbox.io/s/condescending-snow-skuo5?fontsize=14

For a fullscreen experience on your iPhone, visit:
Open it on your iPhone or in XCode with IOS 12+, try scrolling, then focus on an input and try scrolling again.

Answer №1

Just a heads-up for anyone who finds themselves here.

Safari seems to consider this a feature. If you're not a fan of this "feature," there's a bug report here where you can voice your feedback.

When you bring up the keyboard, the browser's window gets pushed up and your content may get hidden as a result of the window being off-screen. Other strange behaviors can also occur, like what was demonstrated by the OP.

https://i.sstatic.net/dBuYh.gif

For more insights and additional examples of peculiar behaviors, refer to this blog post (the image above was taken from it):

Answer №2

After some thorough searching, it appears that the issue lies with iPhones as mentioned in this article:

Unfortunately, using CSS won't solve this problem.

However, you can still utilize JQuery and JavaScript for a workaround :)

Here is a messy workaround specifically for iPhone scenarios. I've tested it with multiple text boxes:

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
...
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>
In summary, the solution addresses the problem where users can scroll away when focusing on a textbox. The idea is to allow user scrolling freedom while smoothly bringing them back to the desired location once they finish. This focuses on the input field.

Problem: User can scroll away while focusing on textbox

As per the assumption,

Solution: Permitting user scrolling control followed by gentle realignment once done; utilizing input:focused

Note: JQuery was used for simplicity. For a pure JavaScript alternative, specific code replacements are available.

Answer №3

Issue Resolved! Simply include the following code in your script

//accessing the input field (Whenever you click to focus)
let inputField = document.getElementById("input_focused")

 /*
 * Method 1: Temporarily change the opacity.
 * Element may "blink" when focused in certain scenarios.
 */
inputField.addEventListener("focus", () => {
      methodOne.style.opacity = 0;
      setTimeout(() => methodOne.style.opacity = 1);
    });
  <section id="modal">
    <input id="input_focused">
  </section>

For more details, please visit https://gist.github.com/kiding/72721a0553fa93198ae2bb6eefaa3299

Answer №4

One can effectively monitor changes in viewport height using JavaScript:

window.visualViewport.addEventListener(
  'resize', 
  event => console.log(event.target)
);

This method has been successfully tested on an iPhone (specifically a physical iPhone 11 with iOS 15.1)

For more information, refer to the MDN documentation: https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

Answer №5

Could you experiment with this CSS and see how it affects the layout?

html {
  height: 100%;
}

body.disable-scroll {
  position: fixed;
  top:0;
  bottom:0;
  left:0;
  right:0;
  height: 100vh;
  overflow: hidden;
}

Answer №6

This technique was really helpful in a recent project of mine...

To prevent scrolling when the keyboard is open, add this code to the body element:

$(body).bind('touchmove', function (e) {
    e.preventDefault()
});

Don't forget to unbind it when you want scrolling to resume:

$(body).unbind('touchmove');

If you also use height:100% or 100vh and overflow:hidden, everything should function smoothly.

Answer №7

To address this issue, the solution involves implementing a script that monitors the appearance of the keyboard. When the keyboard is detected, it will assign the "kb_active" class to the body element and store the new offset value as a data attribute called "data-window-offset". These values can then be utilized in CSS and other JavaScript functionalities.

function monitor_keyboard_status(){
    // For mobile or tablet devices
    if(window.innerWidth < 950) {
        var kb_status = false;
        var initial_screen_size = window.innerHeight; 
        var interval_id = window.setInterval(update_kb_status, 1000);

        function update_kb_status(){
            if(initial_screen_size > window.innerHeight){
                if(!kb_status){
                    var diff = initial_screen_size - window.innerHeight;
                    document.querySelector('body').classList.add('kb_active');
                    document.querySelector('body').setAttribute('data-window-offset', diff);
                    kb_status = true;
                    document.dispatchEvent(new Event("change_keyboard_status"));
                }
            } else {
                if(kb_status){
                    document.querySelector('body').classList.remove('kb_active');
                    document.querySelector('body').removeAttribute('data-window-offset');
                    document.dispatchEvent(new Event("change_keyboard_status"));
                    kb_status = false;
                }
            }
        }
    }
}

Subsequently, we can respond to this event by repositioning elements accordingly.

if(is_ios()){
    document.addEventListener("change_keyboard_status", function(){
        var element = ".nav_box";
        var offset = document.querySelector('body').getAttribute('data-window-offset');
        if(offset && offset > 50){
            if(document.querySelector(element)){
                document.querySelector(element).style.top = offset + "px";
            }
        } else {
            document.querySelector(element).style.top = "";
        }
    });
}


function is_ios() {
    return ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator.platform)
    || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}

Answer №8

This unique feature in iOS prevents the keyboard from obstructing the input field.

To address this issue in my own project, I implemented a solution where the window is scrolled back to the top when the keyboard closes. Additionally, if the window is already scrolling and the keyboard is not open, it automatically scrolls to the top.

var isAppleMobileDevice = true; // custom logic to determine device type

if (isAppleMobileDevice) {

    // Scroll to the top when keyboard closes
    window.addEventListener('focusout', function (e) {
        if (window.scrollY == 0)
            return;

        var isInputField = e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA';
        if (isInputField) {
            window.scrollTo(0, 0);
        }
    });

    // Scroll to the top if keyboard is not open during scroll
    window.addEventListener('scroll', function (e) {
        if (window.scrollY == 0)
            return;

        var isInputFocused = document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA';
        if (!isInputFocused) {
            window.scrollTo(0, 0);
        }
    });

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in displaying selected items list on Sidenav in 365 online platform

In our SharePoint site, we have a parent folder named 'Document' with subfolders '2017' and '2016'. We added these two subfolders to the side navigation bar. However, when selecting either '2016' or '2017' ...

Designing a dynamic grid view for iOS app to display data in multiple columns

Looking to design a multi-column table with individual scrolling for each column. Each column will have expandable sections to accommodate various line items, and the number of sections in each column may vary. Seeking advice on the optimal approach to a ...

Enhance a Javascript object by dynamically introducing new elements

I am currently working on a webpage using HTML and jQuery. My goal is to create a form where users can enter an email address in a textbox, and when they click a button, the email should be added to an object that displays all the emails entered so far. Th ...

Ensuring the secure extraction of HTML coding from messages

When extracting plaintext from messages containing valid and/or invalid HTML, as well as text resembling HTML (e.g. non-HTML text within <...> like: < why would someone do this?? >), it is crucial to retain all non-HTML content while attempting ...

What is the best way to make a div that maintains its size even when the content inside is modified?

My goal is to develop a media feed that includes various types of content such as text, images, and videos. To ensure user safety, I want to conceal any explicit posts with a warning that requires the user to click in order to view the content. Although I ...

What is the best way to design this shape using Flutter?

Looking for assistance on how to create a similar shape in the top right corner of a mobile screen. Here is an example image: https://i.sstatic.net/sHrdW.png Thank you in advance for any help! ...

The React Native Flatlist fails to dynamically adjust the width of the rendered items

I'm currently working on building a messaging interface using a flatlist and a message bubble style from the Nachos-ui UI kit. However, I'm facing some challenges in getting the flatlist to display text bubbles with varying widths based on the le ...

Introducing the new and improved SweetAlert 2.0, the ultimate solution for

I am currently utilizing SweetAlert2.0, known as "This One" <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script> It is functioning properly; however, I would like to display a table, div, or HTML element within this swe ...

Using AngularJS to add external scripts to partials with ng-include

Why won't my main javascript files (located in index.html) work in the partials (such as page1.html)? For example, jQuery and syntax highlighting scripts are not functioning properly when I click on my menu items. HTML CODE: <div data-ng-controll ...

Top method for uploading binary files using Application Loader or Xcode's organizer

What is the most effective method for uploading a binary to the iTunes Store? Is it better to use the Application Loader or to go through the Xcode organizer to archive build, validate, and submit? ...

Guide on transforming the popup hover state into the active state in vue.js through a click event

My code currently includes a popup menu that shows up when I hover over the icon. However, I need to adjust it so that the popup changes its state from hover to active. Intended behavior: When I click the icon, the popup should appear and then disappear w ...

particular shade for button border and background

I'm looking to create a button using Material UI that has a specific design. Right now, I've only been able to achieve this: https://i.stack.imgur.com/xvv7s.png Here is the code I am currently using. If anyone can help me identify what I'm ...

Which is Better: Data-URIs or Embedding Fonts for Icons?

Currently, I am in possession of a set of approximately 10 monotone icons all sized at 25x25 or smaller. I am contemplating between two options for better performance: 1) Incorporating them into CSS using data URIs 2) Utilizing them as a font (for exampl ...

Design a unique border for a div element that extends a top-border all the way through the header and a bottom-border that

I am trying to achieve the design displayed in this mockup: https://i.sstatic.net/sYEPu.png Here is my current progress: https://codepen.io/raney24/pen/VOmjBY .header-border { width: 100%; margin-bottom: 10px; border-left: red solid 1px; border ...

Highcharts: Show tooltip above all elements

Is there a way to configure tooltip display above all elements? I want to define specific coordinates so that the tooltip remains open even if it is covering the chart, and only closes when interacting with the top block. Screenshot 1 Screenshot 2 For e ...

Spilling over: Harnessing the power of flexbox

After searching extensively for a solution on how to control the overflow of a parent container with flexbox, I couldn't find one. So here's another question regarding the same issue. What I want: The problematic part is commented in the HTML co ...

I am facing an issue with my navbar image not aligning properly when using the

I have created a navbar using Bootstrap with the following code: <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Complete Bootstrap 4 Webs ...

Utilizing ABPeoplePickerNavigationController for accessing client information within the core data stack

Currently, I have a core data stack with an entity named 'Client' that includes an 'addressBookID' property linking to the uniqueID of the person in the AddressBook. I am using a fetchedResultsController to populate a basic tableViewCon ...

Tips for Preventing Background Images from Shifting While Minimizing Your Browser

I have searched for solutions, but they all seem to apply only when someone is scrolling. I am in need of a solution where the background image remains static while minimizing the browser window, causing it to be clipped. Full Screen https://i.sstatic.net ...

A combination of Webpack CSS modules with Angular templates

I am currently trying to integrate webpack CSS modules into my angular/ionic project. I'm wondering if it's possible for the CSS module class definitions to be correctly appended to an external template instead of an inline template. When I embe ...