iOS 11 Safari bootstrap modal text area outside of cursor

66,798

Solution 1

I fixed the issue by adding position:fixed to the body when opening a modal. Hope this will help you.

Solution 2

Personally, position: fixed scroll to top automatically. Quite annoying !

To avoid penalizing other devices and versions I apply this fix only to the appropriate versions of iOS.


**VERSION 1 - All modals fix**

For the javascript/jQuery

$(document).ready(function() {

    // Detect ios 11_x_x affected  
    // NEED TO BE UPDATED if new versions are affected
    var ua = navigator.userAgent,
    iOS = /iPad|iPhone|iPod/.test(ua),
    iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua);

    // ios 11 bug caret position
    if ( iOS && iOS11 ) {

        // Add CSS class to body
        $("body").addClass("iosBugFixCaret");

    }

});

For the CSS

/* Apply CSS to iOS affected versions only */
body.iosBugFixCaret.modal-open { position: fixed; width: 100%; }

**VERSION 2 - Selected modals only**

I modified the function to fire only for selected modals with a class .inputModal

Only the modals with inputs should be impacted to avoid the scroll to top.

For the javascript/jQuery

$(document).ready(function() {

    // Detect ios 11_x_x affected
    // NEED TO BE UPDATED if new versions are affected 
    (function iOS_CaretBug() {

        var ua = navigator.userAgent,
        scrollTopPosition,
        iOS = /iPad|iPhone|iPod/.test(ua),
        iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua);

        // ios 11 bug caret position
        if ( iOS && iOS11 ) {

            $(document.body).on('show.bs.modal', function(e) {
                if ( $(e.target).hasClass('inputModal') ) {
                    // Get scroll position before moving top
                    scrollTopPosition = $(document).scrollTop();

                    // Add CSS to body "position: fixed"
                    $("body").addClass("iosBugFixCaret");
                }
            });

            $(document.body).on('hide.bs.modal', function(e) {
                if ( $(e.target).hasClass('inputModal') ) {         
                    // Remove CSS to body "position: fixed"
                    $("body").removeClass("iosBugFixCaret");

                    //Go back to initial position in document
                    $(document).scrollTop(scrollTopPosition);
                }
            });

        }
    })();
});

For the CSS

/* Apply CSS to iOS affected versions only */
body.iosBugFixCaret.modal-open { position: fixed; width: 100%; }

For the HTML Add the class inputModal to the modal

<div class="modal fade inputModal" tabindex="-1" role="dialog">
    ...
</div>

Nota bene The javascript function is now self-invoking


**UPDATE iOS 11.3 - Bug corrected 😃🎉 **

As of iOS 11.3, the bug has been corrected. There is no need to test for OS 11_ in iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua);

But be careful as iOS 11.2 is still widely used (as of April 2018). See

stat 1

stat 2

Solution 3

This issue goes beyond Bootstrap, and beyond just Safari. It is a full display bug in iOS 11 that occurs in all browsers. The fix above does not fix this issue in all instances.

The bug is reported in detail here:

https://medium.com/@eirik.luka/how-to-fix-the-ios-11-input-element-in-fixed-modals-bug-aaf66c7ba3f8

Supposedly they already reported it to Apple as a bug.

Solution 4

Frustrating bug, thanks for identifying it. Otherwise, I would be banging my iphone or my head against the wall.

The simplest fix is (1 line of code change):

Just add the following CSS to the html or to an external css file.

<style type="text/css">
.modal-open { position: fixed; }
</style>

Here is a full working example:

.modal-open { position: fixed; }
<link href="https://getbootstrap.com/docs/3.3/dist/css/bootstrap.min.css" rel="stylesheet">

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@getbootstrap">Open modal for @getbootstrap</button>
...more buttons...

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="exampleModalLabel">New message</h4>
      </div>
      <div class="modal-body">
        <form>
          <div class="form-group">
            <label for="recipient-name" class="control-label">Recipient:</label>
            <input type="text" class="form-control" id="recipient-name">
          </div>
          <div class="form-group">
            <label for="message-text" class="control-label">Message:</label>
            <textarea class="form-control" id="message-text"></textarea>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Send message</button>
      </div>
    </div>
  </div>
</div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://getbootstrap.com/docs/3.3/dist/js/bootstrap.min.js"></script>

I submitted an issue here: https://github.com/twbs/bootstrap/issues/24059

Solution 5

Easiest/cleanest solution:

body.modal-open { position: fixed; width: 100%; }
Share:
66,798

Related videos on Youtube

kekkeme
Author by

kekkeme

Updated on July 08, 2022

Comments

  • kekkeme
    kekkeme almost 2 years

    With iOS 11 safari, input textbox cursor are outside of input textbox. We did not get why it is having this problem. As you can see my focused text box is email text input but my cursor is outside of it. This only happens with iOS 11 Safari

    Problem

  • lfkwtz
    lfkwtz over 6 years
    This should be the answer. Bootstrap adds the modal-open class to the body when a modal is visible. You just need to target that class.
  • timmyc
    timmyc over 6 years
    Note per answers below -- Bootstrap adds .modal-open to body when the modal is open, so you can simply add position: fixed to that class.
  • Nearpoint
    Nearpoint over 6 years
    I have been dealing with this issue for some time. This solution is inadequate for me as adding position fixed scrolls the page back to the top. So when the user closes the modal, they are at a different scroll position. This leads to a terrible user experience
  • hackingchemist
    hackingchemist over 6 years
    This seems to be the issue for me, was working fine before updating to IOS 11. Android users aren't having the problem.
  • Yermo Lamers
    Yermo Lamers over 6 years
    This has no effect on the bug in question, I'm afraid.
  • Redtopia
    Redtopia over 6 years
    I like this, but you might also want to add width:100%, which will constrain the body to 100% of the device width. Depending on existing markup, that might be an issue.
  • Redtopia
    Redtopia over 6 years
    You might also need to add width:100% to constrain the body width to the device width. In some cases, depending on existing markup, that could be an issue. I also like the solution by @gentleboy (below) so as not to penalize other browsers without the problem, because when setting the body to fixed causes the body to scroll to the top, which is somewhat annoying.
  • Mike Casan Ballester
    Mike Casan Ballester over 6 years
    Nice advice. I do not have this issue but I guess this might be global as answer. I’ll add it after I finish my beers
  • Steve D
    Steve D over 6 years
    Didn't work in my scenario. Changing fixed to absolute can have MANY knock on effects
  • tmo256
    tmo256 over 6 years
    This is the easiest solution, and it works, but the only problem is the cursor disappears altogether. It's not as bad as the initial situation, but there's a usability problem.
  • lfkwtz
    lfkwtz over 6 years
    Weird, I haven't experienced a disappearing cursor
  • Learning
    Learning over 6 years
    Faced same issue today but you saved me day
  • Adam Ross Bowers
    Adam Ross Bowers over 6 years
    Strangely, I had this issue with an application build with meteor-cordova. It seemed like any iOS device running v11+ had this issue. In my case I already had position:fixed applied to the body of the application. Instead I changed it to position:absolute on the html element and it fixed my issue. Thank you Jen!
  • T. Evans
    T. Evans over 6 years
    @gentleboy Why not use a REGEX to find any OS 11? So that way you wouldn't have to update each OS 11 update to your code? something like this iOS11 = /OS 11_(\d{1,2})(_{0,1})(\d{1,2})/.test(us);
  • Mike Casan Ballester
    Mike Casan Ballester over 6 years
    @T.Evans Regex will not give much more performance value but is less readable ;-)
  • Mike Casan Ballester
    Mike Casan Ballester over 6 years
    @RonakK it looks like it is still present in beta 11.2 and 11.3 according to bugs.webkit.org
  • Dan
    Dan over 6 years
    @SteveD - to make it work you should append your modal to <body>. And the <body> should have - position: relative. And when it should work :)
  • Alex Burgos
    Alex Burgos over 6 years
    I also experienced the disappearing cursor, any thoughts as to why that could happen?
  • Devin Walker
    Devin Walker over 6 years
    Yeah I'm also seeing a disappearing cursor for just the first focus event. Subsequent input focuses have the cursor appearing. Very strange. This is only happening in Safari on iOS.
  • Abraham
    Abraham over 6 years
    @T.Evans that regex doesn't work. A correct regex might be something like this: ios11 = /OS 11_(\d{1,2})/.test(ua);
  • bkwdesign
    bkwdesign over 6 years
    Similar to other solutions on this thread, once the modal closes - you're back at the top again. For example: user scrolls through grid of items, launches details in a modal.. and with this fix, when they close the modal.. they are once again at the top of the grid of items again and must re-scroll
  • bkwdesign
    bkwdesign over 6 years
    on my iPhone 7 plus, this fix causes my cursor to disappear altogether
  • MechMK1
    MechMK1 over 6 years
    Your answer is an exact duplicate. Please make sure not to post duplicate answers.
  • David
    David over 6 years
    This fix worked for me in using Chrome on mobile. Was confused at first since .modal-open does not appear in the modal html, but I added it anyway as CSS in my header and it worked.
  • Reado
    Reado over 6 years
    This could be the end of modal forms for us. Even if Apple fixes the issue, it will then be up to the user to update their device to see the working form. Is there not an easier universal way to fix this? What about a poly fill?
  • Neal Jones
    Neal Jones over 6 years
    Do you have a more detailed example for this? I'm guessing I would have the Mount in a function that is called when the modal opens, and then put the Dismount in a function and call that when the modal is closed.
  • Arman Charan
    Arman Charan over 6 years
    Aahh yep. I see what you mean. Please see above for a revised solution. Also; yes the intent is for you to call those functions when mounting and dismounting. Thanks.
  • HADI
    HADI over 6 years
    Position fixed will still take document / body scroll to top. I suggest to grab current scrollTop position on modal open and readd scrollTop value once modal closed. Like this jsfiddle.net/im4aLL/hmvget9x/1
  • Mike Casan Ballester
    Mike Casan Ballester over 6 years
    @HADI Thanks for your comment. I updated the answer ;-)
  • HADI
    HADI over 6 years
    @gentleboy thanks man! BTW you forget to initialize scrollTopPosition
  • C.B.
    C.B. over 6 years
    you saved my life <3
  • grant
    grant over 6 years
    @DevinWalker have you guys ever solved the disappearing cursor issue?
  • Devin Walker
    Devin Walker over 6 years
    @grant no I'm hoping Safari fixes it for us.
  • FlavioEscobar
    FlavioEscobar over 6 years
    I confirm this disappearing cursor bug and it looks like it's caused by using position: fixed on body. I fixed it by using body { position: relative; }, html, body { overflow: hidden } and instead of correcting top position for body, I use position: absolute on modal and use top position correction on modal. I'm going to add a response as well.
  • Swapnil Dalvi
    Swapnil Dalvi over 6 years
    Find out more details on hackernoon.com/…
  • Farveen Hassan
    Farveen Hassan over 6 years
    i think we need to wait till 11.3 . im still waiting
  • Starscream
    Starscream about 6 years
    What do you mean, Apple fixed it ?
  • Eashan
    Eashan about 6 years
    @Starscream yes it's fixed by apple with this software version (iOS 11.3)
  • jilykate
    jilykate almost 6 years
    I suggest you put the last "bug fix" part in the top of your answer : )
  • Hamza Dahmoun
    Hamza Dahmoun about 3 years
    Time saving! Thank you.