A Fix for the iOS Orientationchange Zoom Bug

Posted by Scott on 01/05/2012

People enjoy the ability to pinch and zoom websites on their iPhones, iPads, and iPod Touch devices. Unfortunately, a nasty usability bug exists on iOS that causes a user-zoomable page to scale beyond the width of the viewport when the device’s orientation changes from portrait to landscape. As a result, the page ends up cropped by the viewport, and users have to manually zoom the page back out again after changing orientation: annoying at best, confusing at worst.

The bug has existed for years now; I submitted it to Apple a long, long time ago (The bug report was immediately closed as “duplicate”, meaning someone filed it even longer ago. Complementary example here), but it has never been fixed, not in the iOS4.x updates, and not in iOS5 either. Jeremy Keith recently revived interest in its demise through his post iWish, which does a nice job of highlighting the history of the issue, and the attempts at working around it so far (none of which quite work as we need them to).

The common workaround is to disable the user’s ability to scale the page, which of course fixes the bug by introducing a potentially worse situation. Today, we’re offering a workaround that appears to fix the issue without introducing more problems.

Demo and Code

To test it out yourself, point an actual iOS device (not an emulator) to this test page.

The code for the demo can be found on Github (check the README file for a minified version). Just add the script to your site and it should do it’s thing. Please fork and help improve the code, if you’re so inclined!

How it works

This fix works by listening to the device’s accelerometer to detect when an orientation change is about to occur. When it deems an orientation change imminent, the script disables user zooming, allowing the orientation change to occur properly, with zooming disabled. The script restores zoom again once the device is either oriented close to upright, or after its orientation has changed. This way, user zooming is never disabled while the page is in use.

This fix has been tested on iOS 4 and 5, with expected results. Please post your feedback below!


<div id="commentNumber1" class="commentEntry">
<p>I hereby declare Scott Jehl and Filament Group King of the Internet!

Well done!

	<p class="posted"><a href="#commentNumber1">Comment</a> by

Zach Leatherman on 01/05  at  11:52 PM

<div id="commentNumber2" class="commentEntry">
<p>Like a boss!!!&nbsp; Great work, thank you!!

	<p class="posted"><a href="#commentNumber2">Comment</a> by

Brent on 01/06  at  12:26 AM

<div id="commentNumber3" class="commentEntry">
<p>I can’t zoom initially, shouldn’t I? And I get a maximun-scale=1 set on page load. Zooming works after tilting to landscape mode though, then goes away again when moving to portrait.

	<p class="posted"><a href="#commentNumber3">Comment</a> by

Anton Andreasson on 01/06  at  02:38 AM

<div id="commentNumber4" class="commentEntry">
<p>Also, if I zoom intom a corner (in landscape mode) I get a &gt;1 zoom level when going back to portrait (where I can’t correct it - due to the maximum-scale thing?)

	<p class="posted"><a href="#commentNumber4">Comment</a> by

Anton Andreasson on 01/06  at  02:41 AM

<div id="commentNumber5" class="commentEntry">
<p>And this should work, right? If it does for you then I do not understand anything, stupid me. Because it does not. Work.

	<p class="posted"><a href="#commentNumber5">Comment</a> by

Anonymous coward on 01/06  at  04:58 AM

<div id="commentNumber6" class="commentEntry">
<p>Great work folks!

	<p class="posted"><a href="#commentNumber6">Comment</a> by

Aaron Gustafson on 01/06  at  09:42 AM

<div id="commentNumber7" class="commentEntry">
<p>‘Tis indeed a cunning plan. Seems to work. Excellent

	<p class="posted"><a href="#commentNumber7">Comment</a> by

George Adamson on 01/06  at  09:56 AM

<div id="commentNumber8" class="commentEntry">
<p>Brilliant solution Scott, I’m excited to check this technique out on my test device.

	<p class="posted"><a href="#commentNumber8">Comment</a> by

Brett Jankord on 01/06  at  09:58 AM

<div id="commentNumber9" class="commentEntry">
<p>The Filament Group’s large brains are crushing problems once again. My Heroes!!

	<p class="posted"><a href="#commentNumber9">Comment</a> by

Gray Ghost Visuals on 01/06  at  11:42 AM

<div id="commentNumber10" class="commentEntry">
<p>Awesome! Thank you!!!

	<p class="posted"><a href="#commentNumber10">Comment</a> by

Eric Sorenson on 01/06  at  11:44 AM

<div id="commentNumber11" class="commentEntry">
<p>Thanks so much for the work on this. I’ve noticed the fixes (via github page) don’t work if one zooms in before the orientation change.

	<p class="posted"><a href="#commentNumber11">Comment</a> by

theGareth Lewis on 01/06  at  11:51 AM

<div id="commentNumber12" class="commentEntry">
<p>Looks promising, but when I tried it on my iPhone with iOS5, the page is cropped at the right (it extends past the viewport) after I rotate to landscape.&nbsp; Am I missing something?

	<p class="posted"><a href="#commentNumber12">Comment</a> by

Steven Romalewski on 01/06  at  11:55 AM

<div id="commentNumber13" class="commentEntry">
<p>I’m sorry if my comments above sounded harsh. I want to solve thus as much as anyone here. I just can’t see how to do it in all possible situations (see e.g. The zoom into a corner bug above).

I guess it also comes down to if you want to retain any zoom level between the modes at all and, if so, how they should behave. A good enough solution for me would be to always reset to 100% between mode changes, then (re)enable zoom.

	<p class="posted"><a href="#commentNumber13">Comment</a> by

Anton Andreasson on 01/06  at  01:51 PM

<div id="commentNumber14" class="commentEntry">
<p>Awesome! Thank you!

	<p class="posted"><a href="#commentNumber14">Comment</a> by

jucarii on 01/08  at  07:51 AM

<div id="commentNumber15" class="commentEntry">
<p>I’m also seeing this.

When i go to landscape, scale, then turn back to portrait the page is stuck at > 1 zoom. To fix you just go back to landscape and then back to portrait. Would be nice to work on the first change to portrait.

Great work though, thanks!

	<p class="posted"><a href="#commentNumber15">Comment</a> by

Ryan Freng on 01/09  at  09:31 AM

<div id="commentNumber16" class="commentEntry">
<p>Nice fix! Just a quick note that the test page here: <a href="http://scottjehl.github.com/iOS-Orientationchange-Fix/" rel="nofollow">http://scottjehl.github.com/iOS-Orientationchange-Fix/</a> doesn’t work as it has the fix applied. But the test page here: <a href="http://filamentgroup.com/examples/iosScaleBug/" rel="nofollow">http://filamentgroup.com/examples/iosScaleBug/</a> replicates the bug. Had me scratching my head for awhile.

	<p class="posted"><a href="#commentNumber16">Comment</a> by

Tama on 01/09  at  07:42 PM

<div id="commentNumber17" class="commentEntry fg">
<p>Thanks for the feedback, everyone! If you noticed inconsistent behavior, please drop the fix in the tracker on Github.

Tama - good point. I’ll update the demo page so that it’s clearer that it’s not supposed to reproduce the original bug. Thanks!

	<p class="posted"><a href="#commentNumber17">Comment</a> by

Scott (Filament) on 01/10  at  09:01 AM