IOS 11 Modified Safari Download Text Area Out of Cursor

With iOS 11 Safari, the input cursor is outside the text input field. We did not understand why this is a problem. Since you can see that my focused text box is email text input, but my cursor is outside of it. This only happens with iOS 11 Safari

Problem

+33
html ios mobile-safari ios11 bootstrap-modal
Sep 21 '17 at 8:31 on
source share
13 answers

I fixed the problem by adding position:fixed to the body when opening the modal. Hope this helps you.

+31
Sep 22 '17 at 8:42 on
source share

Personally position: fixed scroll up automatically . Pretty annoying!

To avoid being fined for other devices and versions , I apply this fix only to the corresponding versions of iOS.

For javascript / jQuery

 $(document).ready(function() { // Detect ios 11_0_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_1|OS 11_0_2|OS 11_0_3|OS 11_1|OS 11_1_1|OS 11_1_2|OS 11_2|OS 11_2_1/.test(ua); // ios 11 bug caret position if ( iOS && iOS11 ) { // Add CSS class to body $("body").addClass("iosBugFixCaret"); } }); 

For CSS

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

UPDATE 1 OS version 11.1 is added, because the error is still in this version.

+15
Oct 21 '17 at 17:41
source share

This issue goes beyond Bootstrap beyond Safari. This is a complete display error in iOS 11, which occurs in all browsers. The fix above does not fix this problem in all cases.

This is reported in detail here:

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

Presumably, they already reported this to Apple as an error.

+10
Sep 25 '17 at 4:06 on
source share

The disappointment of the error, thanks for identifying it. Otherwise, I will beat my iphone or head against the wall.

The simplest fix (1 line of code change):

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

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

Here is a complete 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 presented the problem here: https://github.com/twbs/bootstrap/issues/24059

+8
Sep 23 '17 at 5:40 on
source share

The simplest / cleanest solution:

 body.modal-open { position: fixed; width: 100%; } 
+2
Oct 03 '17 at 21:09 on
source share

Add position: fixed; in body when a modal function is open.

 $(document).ready(function($){ $("#myBtn").click(function(){ $("#myModal").modal("show"); }); $("#myModal").on('show.bs.modal', function () { $('body').addClass('body-fixed'); }); $("#myModal").on('hide.bs.modal', function () { $('body').removeClass('body-fixed'); }); }); 
 .body-fixed { position: fixed; width: 100%; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <button type="button" class="btn btn-info btn-lg" id="myBtn">Open Modal</button> <!-- Modal --> <div class="modal fade" id="myModal" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">&times;</button> <h4 class="modal-title">Form</h4> </div> <div class="modal-body"> <div class="form-group"> <label class="control-label">Input #1</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #2</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #3</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #4</label> <input type="text" class="form-control"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> </div> </div> </div> 
+1
Sep 22 '17 at 2:36 on
source share

If someone is looking for a fix in vanilla js that works on iOS> 11.2 and does not require any additional CSS:

 (function() { if (!/(iPhone|iPad|iPod).*(OS 11_[0-2]_[0-5])/.test(navigator.userAgent)) return document.addEventListener('focusin', function(e) { if (!e.target.tagName == 'INPUT' && !e.target.tagName != 'TEXTAREA') return var container = getFixedContainer(e.target) if (!container) return var org_styles = {}; ['position', 'top', 'height'].forEach(function(key) { org_styles[key] = container.style[key] }) toAbsolute(container) e.target.addEventListener('blur', function(v) { restoreStyles(container, org_styles) v.target.removeEventListener(v.type, arguments.callee) }) }) function toAbsolute(modal) { var rect = modal.getBoundingClientRect() modal.style.position = 'absolute' modal.style.top = (document.body.scrollTop + rect.y) + 'px' modal.style.height = (rect.height) + 'px' } function restoreStyles(modal, styles) { for (var key in styles) { modal.style[key] = styles[key] } } function getFixedContainer(elem) { for (; elem && elem !== document; elem = elem.parentNode) { if (window.getComputedStyle(elem).getPropertyValue('position') === 'fixed') return elem } return null } })() 

What it is:

  • Check if Safari browser is enabled on iOS 11.0.0 - 11.2.5
  • Listen to any focusin events on the page
  • If the focused element is input or textarea and is contained in the element with the fixed position, change the position of the container to absolute , and with respect to scrollTop and the original size of the containers.
  • When blurring, restore the container to fixed .
0
Dec 28 '17 at 14:48
source share

Try viewport-fit = cover for the meta viewport.

Take a look at this: https://ayogo.com/blog/ios11-viewport/

-one
Oct 02 '17 at 12:38 on
source share

Cancel modal css and change its position from fixed to absolute

 .modal { position: absolute !important; } 
-one
Oct 26 '17 at 12:34 on
source share

As mentioned as a gentleman, setting the body to: fixed automatically forces the page to scroll up. Setting the position of the container to absolute will cause the latter to appear at the top of its closest located ancestor or body, so if the user scrolls down, he may not even see the modal.

The solution would be to set the body position to fixed and pass scrollTop to the upper or extreme CSS property of the body after correction. When closing a modality, perform the opposite operation to retrieve the scrollTop that the user was on before opening the modal.

Js

 var scroll = $(document).scrollTop(); $("body").css("top", -scroll); $("body").addClass("modal-open"); /* open modal */ [...] $("body").css("top", "0"); $("body").removeClass("modal-open"); $(document).scrollTop(scroll); /* remove modal */ 

CSS

 body.modal-open { overflow: hidden; height: 100%; width: 100%; position: fixed; } 

There is no need to check iOS devices, as this trick should fix the iOS error and work on all devices.

-one
Nov 04 '17 at 2:07 on
source share

The problem, as many people have described, is related to:

 position:fixed 

Now, if you open the modal, you will be thrown into the page title ... To avoid this, I use this solution (next to @ Will's).

First make sure your iOS device:

 var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; 

If the device is iOS - add the class of the iOS device to the body:

 if (iOS) { $('body').addClass('iOS-device'); } 

Make a variable to save the scroll position:

 var scrollPosition; 

Now we find the show.bs.modal event and set the top property of the iOS device for a negative scrollPosition:

 $('.modal').on('show.bs.modal', function() { scrollPosition = $(window).scrollTop(); $('.iOS-device').css('top', -scrollPosition); }); 

Then define the hide.bs.modal event, remove the modal-open class, reset the top value of the iOS device and scroll through the document until it was before the modal was opened:

 $('.modal').on('hide.bs.modal', function() { $('.iOS-device').removeClass('modal-open'); $('.iOS-device').css('top', 0); $(document).scrollTop(scrollPosition); }); 

And the full code:

 ( function() { var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; if (iOS) { $('body').addClass('iOS-device'); } var scrollPosition; $('.modal').on('show.bs.modal', function() { scrollPosition = $(window).scrollTop(); $('.iOS-device').css('top', -scrollPosition); }); $('.modal').on('hide.bs.modal', function() { $('.iOS-device').removeClass('modal-open'); $('.iOS-device').css('top', 0); $(document).scrollTop(scrollPosition); }); })(); 

CSS

 body.modal-open.iOS-device { position: fixed; width: 100%; } 
-one
Nov 07 '17 at 11:03 on
source share

add in #modal position: absolute it will fix future problems related to the position: fixed

-one
Dec 20 '17 at 19:42 on
source share

enter image description here

For these kinds of problems, we found the following 3 solutions

1) Change the container with position: fixed; at position: absolute; . The disadvantage of this is that the user can easily scroll away from the modal, which we would like to take on primarily in the field of real estate.

2) You could argue that the modals do not work on small screens as well, and the best workaround would be to not use the modals at all, but this would be a rather large correspondence in our case, and we needed to be fixed as soon as possible.

3) What we found the best solution in our case is to keep the modal fixed, but stretch it around the edges of the window, hiding the rest of the contents in the body using display: none; . This will eliminate the problem of body growth higher than the viewing area, and when focusing on the input there will be no background scrolling.

-2
Dec 08 '17 at 8:39 on
source share



All Articles