Fixing the iOS orientation / viewport zoom bug
Jeff discovered an iPad and iPhone related issue with scale while working on and testing an independent project with a responsive layout - and found a solution on Stack Overflow which could use some publicity (and possibly some further eyes on the code).
Jeremy Keith’s post on Orientation and Scale summed up the issue as well as the solution used here. Jeff’s development project deals with a layout that is 3 columns on iPad landscape, and 2 columns on iPad portrait.
Using just the standard responsive scale meta tag, the site loaded in landscape correctly:

When turned to portrait, the site adjusted appropriately - great:

But when turned back to landscape - ehh:

By default the iPad changes the scale of document when going from portrait to landscape.
Here’s the fix:
Retaining the current responsive meta tag code is best, as it continues to give a fallback user the ability to scale the page using the pinch gesture (whereas locking the user into a scale of 1 off the bat automatically denies that feature).
<meta name=”viewport” content=”width=device-width, initial-scale=1”>
Rather, we place that responsibility with the Javascript. Here’s the Javascript fix:
if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) { var viewportmeta = document.querySelector('meta[name="viewport"]'); if (viewportmeta) { viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0'; document.body.addEventListener('gesturestart', function() { viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6'; }, false); } }To sum up the Javascript, it begins by disabling page scaling, so that if the device orientation is changed, there is no change in page scale. But then, if the user requests to zoom in on the page by making a pinch gesture, page scale is triggered back on (in which case, we lose our control over scale when changing between orientations).
And like magic, Jeff’s layout now retains its appropriate scale when changed between orientations. The solution isn’t 100% flawless - with some delay when scale is triggered back on by the user’s pinch. Again, thanks go out to the Adactio post, where Jeremy Keith goes over the solution and changes made along the way in detail.
5 Comments
1
Stéphanie says
Hi Mike, nice trick, I tried it on an iPad 1 but unfortunately the "zoom" function with pinch does not work when the script is activated :/ Any idea ?
2
Christina Beymer says
Never mind. It works. Refreshing the page is refreshing
3
Christina Beymer says
I added this and it works, but the zooming on an ios doesn't work anymore.
4
Mike Swartz says
Haven't tried it, but if you do, let us know!
5
iamkeir says
This is super neat ...but is there a way to re-disable zooming once the user has zoomed back out again? At the moment, I'm using a timeout which is not ideal.