Create a gist now

Instantly share code, notes, and snippets.

Embed
Improved version of JavaScript fix for the iOS viewport scaling bug. See http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewport-scale-bug/
// Original code form http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewport-scale-bug/
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";
}
}
}
// My rewritten version
(function() {
var metas = document.querySelectorAll('meta[name="viewport"]'),
forEach = [].forEach;
function fixMetas(firstTime) {
forEach.call(metas, function(el) {
el.content = firstTime
? 'width=device-width,minimum-scale=1.0,maximum-scale=1.0'
: 'width=device-width,minimum-scale=0.25,maximum-scale=1.6';
});
}
fixMetas(true);
document.body.addEventListener('gesturestart', fixMetas, false);
}());
@mathiasbynens

This comment has been minimized.

Show comment
Hide comment
@mathiasbynens

mathiasbynens Apr 4, 2011

Demo (try on iOS): http://mathiasbynens.be/demo/ios-viewport-scaling

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.
Owner

mathiasbynens commented Apr 4, 2011

Demo (try on iOS): http://mathiasbynens.be/demo/ios-viewport-scaling

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

This comment has been minimized.

Show comment
Hide comment
@shichuan

shichuan 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?

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

This comment has been minimized.

Show comment
Hide comment
@beep

beep Apr 4, 2011

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

beep commented Apr 4, 2011

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

@jsteenkamp

This comment has been minimized.

Show comment
Hide comment
@jsteenkamp

jsteenkamp Apr 6, 2011

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

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

@mathiasbynens

This comment has been minimized.

Show comment
Hide comment
@mathiasbynens

mathiasbynens Apr 12, 2011

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

Owner

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

This comment has been minimized.

Show comment
Hide comment
@ibrent

ibrent Aug 21, 2011

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

ibrent commented Aug 21, 2011

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

@ShaggyDude

This comment has been minimized.

Show comment
Hide comment
@ShaggyDude

ShaggyDude Aug 24, 2011

I agree with ibrent. Nice job.

I agree with ibrent. Nice job.

@mathiasbynens

This comment has been minimized.

Show comment
Hide comment
@mathiasbynens

mathiasbynens Sep 21, 2011

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

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    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.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.
Owner

mathiasbynens commented Sep 21, 2011

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

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    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.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.
@darrylhebbes

This comment has been minimized.

Show comment
Hide comment
@darrylhebbes

darrylhebbes Oct 14, 2011

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

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

@bcorreia

This comment has been minimized.

Show comment
Hide comment
@bcorreia

bcorreia 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.

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.

@ShaggyDude

This comment has been minimized.

Show comment
Hide comment
@ShaggyDude

ShaggyDude Nov 4, 2011

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.

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.

@matthew-dean

This comment has been minimized.

Show comment
Hide comment
@matthew-dean

matthew-dean Dec 1, 2011

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.

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

This comment has been minimized.

Show comment
Hide comment
@MarkFull

MarkFull Dec 6, 2011

Any test on iOS 4.3.3?

MarkFull commented Dec 6, 2011

Any test on iOS 4.3.3?

@atsea

This comment has been minimized.

Show comment
Hide comment
@atsea

atsea Dec 8, 2011

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

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

@sergiolopes

This comment has been minimized.

Show comment
Hide comment
@sergiolopes

sergiolopes Feb 28, 2012

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

https://github.com/sergiolopes/ios-zoom-bug-fix

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

https://github.com/sergiolopes/ios-zoom-bug-fix

@mohsen1

This comment has been minimized.

Show comment
Hide comment
@mohsen1

mohsen1 Mar 27, 2012

I face palmed
document.getElementsByTagName('body')[0]

mohsen1 commented Mar 27, 2012

I face palmed
document.getElementsByTagName('body')[0]

@matthew-dean

This comment has been minimized.

Show comment
Hide comment
@matthew-dean

matthew-dean Mar 27, 2012

You mean because of document.body? ;-)

You mean because of document.body? ;-)

@yahreen

This comment has been minimized.

Show comment
Hide comment
@yahreen

yahreen 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.

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.

@davidpaulsson

This comment has been minimized.

Show comment
Hide comment
@davidpaulsson

davidpaulsson Oct 4, 2012

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

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

@mihaipaun

This comment has been minimized.

Show comment
Hide comment
@mihaipaun

mihaipaun Nov 5, 2012

Yes, it's fixed as of iOS6: http://adactio.com/journal/5802/

Yes, it's fixed as of iOS6: http://adactio.com/journal/5802/

@AlecRust

This comment has been minimized.

Show comment
Hide comment
@AlecRust

AlecRust Nov 29, 2012

What about this CSS-only solution? http://stackoverflow.com/a/8727440/312681

What about this CSS-only solution? http://stackoverflow.com/a/8727440/312681

@AlecRust

This comment has been minimized.

Show comment
Hide comment
@AlecRust

AlecRust Nov 29, 2012

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

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

@benjamincharity

This comment has been minimized.

Show comment
Hide comment
@benjamincharity

benjamincharity Feb 16, 2013

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.

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.

@moizsaif123

This comment has been minimized.

Show comment
Hide comment
@moizsaif123

moizsaif123 Apr 11, 2013

http://mathiasbynens.be/demo/ios-viewport-scaling

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

http://mathiasbynens.be/demo/ios-viewport-scaling

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

This comment has been minimized.

Show comment
Hide comment
@sila1

sila1 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!

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

This comment has been minimized.

Show comment
Hide comment
@ddantes

ddantes 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 http://mauitradewinds.com/test/view.htm you will see a horizontally-scrolling image with a fixed text caption. The viewport bug fix works perfectly. But, at http://mauitradewinds.com/test/test.htm 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.

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 http://mauitradewinds.com/test/view.htm you will see a horizontally-scrolling image with a fixed text caption. The viewport bug fix works perfectly. But, at http://mauitradewinds.com/test/test.htm 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.

@ericmuyser

This comment has been minimized.

Show comment
Hide comment
@ericmuyser

ericmuyser Nov 15, 2013

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

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

@enure

This comment has been minimized.

Show comment
Hide comment
@enure

enure Feb 10, 2014

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

enure commented Feb 10, 2014

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

@jpblancoder

This comment has been minimized.

Show comment
Hide comment
@jpblancoder

jpblancoder Jul 29, 2014

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);
    }

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);
    }
@DaveFlash

This comment has been minimized.

Show comment
Hide comment
@DaveFlash

DaveFlash Jul 28, 2016

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

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

@HarroH

This comment has been minimized.

Show comment
Hide comment
@HarroH

HarroH Aug 11, 2017

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

HarroH commented Aug 11, 2017

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

@webaffin

This comment has been minimized.

Show comment
Hide comment
@webaffin

webaffin Aug 21, 2017

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

I also want to know...

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

I also want to know...

@GraniteConsultingReviews

This comment has been minimized.

Show comment
Hide comment
@GraniteConsultingReviews

GraniteConsultingReviews Sep 4, 2017

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

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

@Rustygames

This comment has been minimized.

Show comment
Hide comment
@Rustygames

Rustygames Oct 18, 2017

I don't think this works any more (iOS 10+) due to Apple now ignoring the scale meta tags

I don't think this works any more (iOS 10+) due to Apple now ignoring the scale meta tags

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