1

In mobile safari on iOS 8, when I follow a link to open a new window (which has a <meta name="viewport" content="width=device-width, initial-scale=1.0">), the page intermittently appears scrolled way up (i.e. there is a big gap between the top of the viewport and the first element of the page).

Scrolling at all after that brings behaviour back to normal. This is very frustrating, what is the most reliable workaround?

Example page

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style type="text/css">
      body {
        margin:0;
      }
      h1 {
        background-color:red;
        margin:0;
      }
    </style>

  </head>
  <body>
    <h1>Top of page</h1>
  </body>

</html>

Screenshot

Bug report under rdar://20598527

diachedelic
  • 2,195
  • 1
  • 24
  • 28

1 Answers1

1

It looks like this rogue scrolling occurs as or just after the page first paints. This could probably be before or after DOM ready, window load events fire.

My hacky solution (see gist) is to run incrementally window.scrollTo(0, 1); until the danger has passed, only on Mobile Safari.

Fixed source:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style type="text/css">
      body {
        margin:0;
      }
      h1 {
        background-color:red;
        margin:0;
      }
    </style>
  </head>
  <body>
    <h1>Top of page</h1>

    <script>
      // Fixes rdar://20598527 (http://openradar.appspot.com/radar?id=6113789778853888)
      // Use and modify this code with no restriction whatsoever.
      // Place just before closing body tag

      var ua = window.navigator.userAgent;
      var iOS = ua.match(/iPad/i) || ua.match(/iPhone/i);
      var webkit = ua.match(/WebKit/i);
      var chrome = ua.match(/CriOS/i);
      var mobileSafari = iOS && webkit && !chrome;
      if (mobileSafari) {
        var duration = 500; // ms
        var start = Date.now();
        var id = setInterval(function() {
          window.scrollTo(0, 1);

          if (Date.now() - duration > start) {
            clearInterval(id);
          }
        }, 10);
      }
    </script>
  </body>

</html>
Community
  • 1
  • 1
diachedelic
  • 2,195
  • 1
  • 24
  • 28