iOS 7 iPad Safari Landscape innerHeight/outerHeight layout issue

42,646

Solution 1

In my case, the solution was to change positioning to fixed:

@media (orientation:landscape) {
    html.ipad.ios7 > body {
        position: fixed;
        bottom: 0;
        width:100%;
        height: 672px !important;
    }
}

I also used a script to detect iPad with iOS 7:

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
    $('html').addClass('ipad ios7');
}

Solution 2

Simple, cleaner CSS-Only solution:

html {
     height: 100%;
     position: fixed;
     width: 100%;
   }

iOS 7 seems to set the height correctly with this. Also there is no need for resize javascript events, etc. Since you are working with a full height app, it doesn't really matter if it is always position fixed.

Solution 3

Samuel's answer, as also stated by Terry Thorsen, is working great, but fails in case the webpage has been added to the iOS home.

A more intuitive fix would be to check for window.navigator.standalone var.

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && !window.navigator.standalone) {
    $('html').addClass('ipad ios7');
}

This way it only applies when opened inside Safari, and not if launched from home.

Solution 4

Samuel's answer is the best although it breaks if a user adds the page to their home screen (home screen pages don't exhibit the bug). Check the innerHeight before adding the class like so:

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
    if(window.innerHeight==672){
        $('html').addClass('ipad ios7');
    }
}

Note that the bug also does not exhibit under webview.

Solution 5

I used this JavaScript solution for solving that problem:

    if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && window.innerHeight != document.documentElement.clientHeight) {
  var fixViewportHeight = function() {
    document.documentElement.style.height = window.innerHeight + "px";
    if (document.body.scrollTop !== 0) {
      window.scrollTo(0, 0);
    }
  }.bind(this);

  window.addEventListener("scroll", fixViewportHeight, false);
  window.addEventListener("orientationchange", fixViewportHeight, false);
  fixViewportHeight();

  document.body.style.webkitTransform = "translate3d(0,0,0)";
}
Share:
42,646
hisnameisjimmy
Author by

hisnameisjimmy

Too weird to live, and too rare to die

Updated on July 05, 2022

Comments

  • hisnameisjimmy
    hisnameisjimmy almost 2 years

    We're seeing issues with a web app that has a height of 100% on Safari in iOS 7. It appears that the window.innerHeight (672px) doesn't match window.outerHeight (692px), but only in landscape mode. What ends up happening is that in an app with 100% height on the body, you get 20px of extra space. This means that when a user swipes up on our app, the navigation elements get pulled behind the browser chrome. It also means that any absolutely positioned elements that are at the bottom of the screen end up being 20px off.

    This issue was also outlined in this question here: IOS 7 - css - html height - 100% = 692px

    And can be seen in this ambiguous screenshot: iOS 7 Safari outerHeight issue

    What we're trying to do is hack around this so that until Apple fixes the bug, we don't have to worry about it.

    One way of doing this is to absolutely position the body only in iOS 7, but this pretty much puts the extra 20px at the top of the page instead of the bottom:

    body {
        position: absolute;
        bottom: 0;
        height: 672px !important;
    }
    

    Any help with forcing outerHeight to match innerHeight, or hacking around it so that our users can't see this issue would be much appreciated.

  • agudulin
    agudulin over 10 years
    You don't actually solve the problem, because there is a strange white space at the bottom of the page (look here) and user still can scroll the page.
  • hisnameisjimmy
    hisnameisjimmy over 10 years
    I combined this with doing window.scrollTo(0,0); on orientation change and it seems to have solved 99% of our problems. Give me a couple days of using this in production and I think we might have our answer.
  • Gino
    Gino over 10 years
    I just found that a friend with the iPad mini OS 7 do not have this problem, any idea to find if it's iPad mini?
  • Esger
    Esger over 10 years
    My iPad reports window.innerHeight of 671 (with console.log), so 672 is not always accurate.
  • Geek_Akash
    Geek_Akash about 10 years
    i have an iPad mini with retina and seeing the same problem
  • Christopher Reid
    Christopher Reid about 10 years
    Wow... I can't believe it took me so long to find this. I've been searching all night trying weird javascript hacks that almost but never worked. This is amazing.
  • jscharf
    jscharf over 9 years
    This works on a regular iPad w/ Retina, but does not work on an iPad Mini, strangely. The 672px fix seems to work on both.
  • Chris Gunawardena
    Chris Gunawardena over 9 years
    OMG wasted about two days on this on the ipad sim thinking my postion:absolute; was casuing this. Thanks!
  • Nick Hingston
    Nick Hingston about 9 years
    another situation this doesn't work in is when the favorites bar is showing. So with this answer and mine bellow - all issues covered (as far as I'm aware!)