scottjehl/Device-Bugs

iOS 6-7 handles viewport relative units really weird

Opened this issue · 11 comments

Summary:

When setting a viewport relative unit on an element, the measurement seems to change on the next layout, since the total height of the internal representation of the viewport (however that works) is now the height of the total content including the recently rendered viewport-relative element. So content that makes the viewport-behind-the-scenes larger (for example, using height: 100vh will be 100vh + rest of the content on the next pass, and so on.

Effect is that the viewport relative element grows in size for each layout calculation.

The description of how the browser handles the viewport on different levels is deliberately fuzzy: I really have no idea of what goes on behind the scenes, but it ain't working with the visual viewport.

EDIT: Trying to simplify the example now, I can see that it's not always happening. Currently trying to reduce the case further. Seems like it takes a bit for the bug to appear, but changing any content inside the element or changing other layout related properties such as padding triggers the miscalculation, but simply scrolling, changing the background etc does not.

Platforms:

  • Mobile Safari/WebViews, iOS 6 - 7. Fixed in iOS 8.

How to reproduce:

  1. Create an element that has height: 100vh set in CSS, and some more content on the same page.
  2. Scroll, change orientation or otherwise cause the browser to recalculate layout.

Reduced Example:

http://jsbin.com/ikediy/39/ - warning: might crash Mobile Safari after a while.

Bug Tracker ticket(s):

Reported to Apple as bug no. 14437801

Workarounds:

None that I know of.

Still present in iOS7. Le sigh.

Confirm. Same bug for me.

I have a similar problem on http://alwaysreadthemanual.com/issues/4/wilson-miner/article, which presents a simple case which reproduces the bug without height:100vh, but a simple max-height with viewport height units.

It seems that the issue has nothing to do with the specific value of the vh unit, but just any layout-recalculating event, user-triggered or not, which, as @emilbjorklund said, makes internal value of the viewport height equal to the content height.

On the URL I mentioned, this only happens under 850px, when the illustration is stacked above the title and synopsis, (as the code is wrapped inside a media query). It is very straightforward:

<div class="issue-piece-header-illustration">
    <figure>
      <img src="..." alt=""/>
    </figure>
</div>

Note the max-height declaration:

.issue-piece-header-illustration img {
    max-height: 65vh;
    max-width: 100%;
    display: block;
}

For the screenshots below, I’ve added a background: blue to the wrapping figure to make it easier to see if the img spans its entire available width.

Three tests:

  1. On iOS, this doesn’t work: http://cl.ly/image/3R1c3s1Q211B (it does on Safari for Mac)
  2. However, when I remove all the article text, it seems to work: http://cl.ly/image/1J191q00473Q
  3. If the article text is present, setting max-height to 5vh, seems to work too: http://cl.ly/image/0G2W3l2f1n0r

So, it’s apparent that vh units work, it's just that the viewport height becomes the content height, which on very long pages like mine, makes it irrelevant.

However, the difference for me is that it happened without scrolling or orientation change, which was intriguing. So I removed all the <script> tags from my page, and it seems that the Typekit code, in either of its versions, causes a layout recalculation, triggering the bug. It still happens with orientation changes, but not on scrolling or zooming.

I haven’t found a workaround yet, other than not having any layout recalculating code, which isn’t very practical.

UPDATE: I’ve added this bug to Webkit’s Bugzilla as Bug 127771: https://bugs.webkit.org/show_bug.cgi?id=127771

I work on a PHPBB forum where I have user's profile pics scale with the browser by using:

.postprofile img {
width: 66%;
height: auto;
}

Works great on all browsers except older versions (esp. iOS 6) of Safari, which "smear" the image down the entire length of the screen. (You can see this on the LHS of the screen in the attached image.) Wondering if it could be the same issue described in this bug report?

screenshot

Fixed in iOS8. Yesssss!

Has anyone came up with a solution for this?

I recently had the same problem. My solution:
CSS:

header { min-height:100vh; }

JS for ios:

var iOS = navigator.userAgent.match(/(iPod|iPhone|iPad)/);
if(iOS){

    function iosVhHeightBug() {
        var height = $(window).height();
        $("header").css('min-height', height);
    }

    iosVhHeightBug();
    $(window).bind('resize', iosVhHeightBug);

}  

Is this confirmed as fixed in iOS 8?

Seems to be fixed in IOS 8, we can't reproduce it there. https://github.com/rodneyrehm/viewport-units-buggyfill fixed it for IOS < 8

Yup, that's my conclusion as well + I just checked and Apple has marked my bug as closed in the bug tracker. So yay!