Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Improved version of JavaScript fix for the iOS viewport scaling bug. See
// Original code from
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
document.getElementsByTagName('body')[0].addEventListener("gesturestart", gestureStart, false);
function gestureStart() {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
// Rewritten version
// By @mathias, @cheeaun and @jdalton
(function(doc) {
var addEvent = 'addEventListener',
type = 'gesturestart',
qsa = 'querySelectorAll',
scales = [1, 1],
meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];
function fix() {
meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];
doc.removeEventListener(type, fix, true);
if ((meta = meta[meta.length - 1]) && addEvent in doc) {
scales = [.25, 1.6];
doc[addEvent](type, fix, true);

mathiasbynens commented Apr 4, 2011

Demo (try on iOS):

Just like the original script, this snippet locks zooming by setting both minimum-scale and maximum-scale to 1.0 on load, effectively overwriting the values specified in the HTML, e.g.

<meta name="viewport" content="width=device-width,initial-scale=1.0">

By locking these values, zooming is disabled, even when the orientation of the device changes (which would normally trigger the zoom bug).

The script also accounts for the case where there are multiple meta name="viewport" elements in the HTML. I know, it should never happen — but we take care of it just in case.

This script is effectively the same as the original; only the code changed. No bugs were fixed, no features were added. Some important notes:

  1. As soon as the user makes a gesture on the document, zooming is enabled again, so if you change the device orientation after that, the zoom bug will still occur.
  2. The user can only effectively start zooming after starting a second gesture.

shichuan commented Apr 4, 2011

  1. for the first problem, i am aware of this, additional event handling can be added (on orientation change). but the idea is if someone wants to zoom the text, he may not care about the bug.
  2. this one i can't replicate, if u experience this, can try touchmove?

beep commented Apr 4, 2011

I can confirm that #1 and #2 occurs for me (iPhone 3GS, iOS 4.3.1).

I can confirm #1 and #2 on iPod touch 4, iOS 4.3.1


mathiasbynens commented Apr 12, 2011

@jdalton’s rewrite was so good I ported most of his changes back to this gist for future reference.

ibrent commented Aug 21, 2011

Works brilliantly, thank you !!! Very tight nice code too. Like art.

I agree with ibrent. Nice job.


mathiasbynens commented Sep 21, 2011

@mbjwork: The license is as liberal as it gets:

                    Version 2, December 2004

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.



Tested and working on iPhone 3G with OS 3.1.2 of Safari

bcorreia commented Nov 2, 2011

Any idea on how to modify this script to make it work when the initial scale has to be 0.5 instead of 1.0? — Please, any help is always welcome.

Hmm, could you not just pull in the min/max from the actual meta tags and only override them if not present?
That might be best for dumb designers like me.

This doesn't seem to fix the bug at all. The point of maximum scale is to lock the width to the width of the device. After zooming with this script, when changing orientation, it still has the problem of being too big.

Also, requiring two gestures seems clunky.

MarkFull commented Dec 6, 2011

Any test on iOS 4.3.3?

atsea commented Dec 8, 2011

Confirmed working on iPad 4.3.5 (8L1) and iPhone 4G 5.0.1
Confirmed NOT working on iPod 5.0

I think I got a better solution to this bug (just submitted to MBP for evaluation and maybe integration):

mohsen1 commented Mar 27, 2012

I face palmed

You mean because of document.body? ;-)

yahreen commented Jun 29, 2012

This works great but I've noticed it is adversely affecting my href links.

I have my nav links set to width="100%". If I use my finger to scroll and a link is below my finger, it triggers the :hover state of the link (in this case a background color). I'm assuming it has to do with gesturestart. It happens in both the original script as well as in this improved one.

I've heard rumors that this is fixed in iOS6. Can someone confirm this?

Yes, it's fixed as of iOS6:

What about this CSS-only solution?

@mihaipaun not as far as I can tell...

If that bug was fixed there should be some release information on it somewhere. I'd love to see a link on this to know if it truly is supposed to be fixed. I too have heard the rumors.

I read through what I could find on the iOS 6 release with no luck.

In order for the script to work and bypass the 2nd gesture minor tweaking like in orienatation change event set the max to 1.00099 instead of just 1.0

sila1 commented Jul 3, 2013

hi, i'm still in a learning process and really grateful to all sites like this one!

the code works fine with me. the only thing is that a tiny part of the page is being cut off from the sides. is there a way of preventing this or is it possibly a self-inflicted problem because i made my page 1000px wide?

i'd be very grateful to any help and ideas!

ddantes commented Jul 12, 2013

I appreciate this code, which has helped me as I've adapted my website to be more mobile friendly. I'm posting about an issue which just came to my attention, hoping for some advice. It seems that the bug fix doesn't work if a page includes dynamic text. I have two pages which implement the bug fix, although the script is external in a file named MaintainViewport.js. If you visit you will see a horizontally-scrolling image with a fixed text caption. The viewport bug fix works perfectly. But, at there is a fading caption below the scrolling image. The viewport bug is not fixed on this page, although it references the same javascript to correct that bug. If I remove the dynamic caption, the viewport bug also disappears. If there is a solution to this, I'd be grateful to see it.

}(document));? should be })(document);

enure commented Feb 10, 2014

@ericmuyser - you can write it either way. The latter is more common, but the former works as well.

You might want to update with additional meta params, for iOS 6+.

function fix() {
        meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=' + scales[1] + ', user-scalable=no, minimum-scale=' + scales[0];
        doc.removeEventListener(type, fix, true);

hmm, still seems to create problems for me....

HarroH commented Aug 11, 2017

Is this fix still applicable to iOS or has Apple solved this issue?

Is this fix still applicable to iOS or has Apple solved this issue?

I also want to know...

I tested this code and its working well. thanks for sharing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment