Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS7 Safari layout breaks on orientation change if input is focused

It seems that there is a fundamental breakage in iOS7 iphone/ipad and possibly/likely other versions.

If you focus on an input field so that the keyboard is open, the layout breaks in a terrible and irrecoverable way on orientation change. It has nothing to do with css I only added it so that the problem can be seen clearer.

Changing the orientation back fixes the layout but I can't find another way.

Demo

To load on an iPad/iPhone: http://dominictobias.com/ios-layout-bug/

Update: only breaks with maximum-scale=1 on meta viewport which stops Safari zooming in when you change orientation.

Updated 2: Here is another fun bug with meta viewport:

<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">

If you do this and change orientation, it zooms in and then you cannot zoom out and see the whole website again - even refreshing doesn't work. You have to create a new tab to get back to a normal zoom level.

Updated 3: Rather than consider this a major bug Apple support asked me if it is happening on iOS 8 beta and marked the bug as No Rank.

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
    <title>iOS7 Layout break</title>

    <style>
    body {
        background-color: red;
        margin: 0;
        padding: 0;
    }
    .container {
        background-color: black;
    }
    .inner-container {
        max-width: 75%;
        margin: 0 auto;
        padding: 30px;
        background-color: white;
    }
    </style>
</head>
<body>

<div class="container">
    <div class="inner-container">
        <p>When you focus in on this field and change orientation, iOS7 (possibly other versions) will completely break by rendering some of the content off screen on the left and there seems to be no way to fix it by causing a repain - the node tree all the way up to the root thinks the width of the browser is now less than it was..</p>
        <input type="text">
    </div>
</div>

</body>
</html>

 When first focusing in:

At first when focused in

 Then all hell breaks loose, all the way up to the <html> element the width is as wide as the red bit, a lot of the site is disappearing into left space (off view, no scrollbar):

All hell breaks loose on orientation change

 If you do orientation change back and then back again the browser starts to think it's a main character in the Inception film:

enter image description here

So.. solutions? Will I have to listen for orientation change and programmatically focus out of the input before it breaks? Edit: tried this it didn't work (not quick enough).

like image 976
Dominic Avatar asked Jul 30 '14 15:07

Dominic


1 Answers

I came across this issue but came up with a plausible solution.

  • Create a reference to the input field within your applications global scope (ensure you can access it later) when focusing on it. I set the default value to NULL.

  • In your orientation change handler check if the reference is not NULL, if NOT then execute window.scroll(0,0). execute another function in a timeout to scroll to that input field; window.scroll(0,activeInput.offset().top);

Note: I have set the timeout to about 1000 which is enough for the browser to "repaint". I'm not a fan of this but it works!

Code example:

var activeInput = null;
$(":input").focusin(function (e) {
    activeInput = $(this);
});
$(window).orientationChange(function(){
   if(activeInput!=null)window.scroll(0,0);
   setTimeout(function(){window.scroll(0,activeInput.offset().top},100);
});

Another solution if you don't care if the user loses the keyboard, is:

$(":input").blur(function (e) {
    window.scroll(0,0);
});
$(":input").focusout(function (e) {
    window.scroll(0,0);
});
activeInput.blur();

Hope this helps!

like image 82
thecommoner Avatar answered Oct 26 '22 11:10

thecommoner