A Fix for the iOS Orientationchange Zoom Bug

Posted by Scott on 01/06/2012

Topics:

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!

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site

Comments

I hereby declare Scott Jehl and Filament Group King of the Internet!

Well done!

Comment by Zach Leatherman on 01/06  at  07:52 AM

Like a boss!!!  Great work, thank you!!

Comment by Brent on 01/06  at  08:26 AM

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.

Comment by Anton Andreasson on 01/06  at  10:38 AM

Also, if I zoom intom a corner (in landscape mode) I get a >1 zoom level when going back to portrait (where I can’t correct it - due to the maximum-scale thing?)

Comment by Anton Andreasson on 01/06  at  10:41 AM

And this should work, right? If it does for you then I do not understand anything, stupid me. Because it does not. Work.

Comment by Anonymous coward on 01/06  at  12:58 PM

Great work folks!

Comment by Aaron Gustafson on 01/06  at  05:42 PM

‘Tis indeed a cunning plan. Seems to work. Excellent

Comment by George Adamson on 01/06  at  05:56 PM

Brilliant solution Scott, I’m excited to check this technique out on my test device.

Comment by Brett Jankord on 01/06  at  05:58 PM

The Filament Group’s large brains are crushing problems once again. My Heroes!!

Comment by Gray Ghost Visuals on 01/06  at  07:42 PM

Awesome! Thank you!!!

Comment by Eric Sorenson on 01/06  at  07:44 PM

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.

Comment by theGareth Lewis on 01/06  at  07:51 PM

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.  Am I missing something?

Comment by Steven Romalewski on 01/06  at  07:55 PM

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.

Comment by Anton Andreasson on 01/06  at  09:51 PM

Awesome! Thank you!

Comment by jucarii on 01/08  at  03:51 PM

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!

Comment by Ryan Freng on 01/09  at  05:31 PM

Nice fix! Just a quick note that the test page here: http://scottjehl.github.com/iOS-Orientationchange-Fix/ doesn’t work as it has the fix applied. But the test page here: http://filamentgroup.com/examples/iosScaleBug/ replicates the bug. Had me scratching my head for awhile.

Comment by Tama on 01/10  at  03:42 AM

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!

Comment by Scott (Filament) on 01/10  at  05:01 PM

Commenting is closed for this post.

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site