iPad layout scales up when rotating from portrait to landscape
HtmlIpadMeta TagsViewportHtml Problem Overview
I have a added to the "viewport"
meta tag "width=device-width,initial-scale=1.0"
and on an iPad the page loads up fine in landscape mode, the it switches nicely to portrait and when I rotate it back to landscape it scales the page up and I have to pinch zoom it back to a 1 scale.
I can fix this by adding the "maximum-scale=1.0, user-scalable=no"
, but I was wondering if there is a way I could fix this without taking away from the user the ability to zoom in the page.
If you have any suggestions I would love to hear them,
Thanks!
Html Solutions
Solution 1 - Html
------ Update ------
This is not an issue anymore in iOS7. And there is better fix by Scott Jehl on github scottjehl/iOS-Orientationchange-Fix that works for iOS6.
------ Original answer ------
Jeremy Keith (@adactio) has a good solution for this on his blog Orientation and scale
Keep the Markup scalable
<meta name="viewport" content="width=device-width, initial-scale=1">
Then disable scalability with javascript until gesturestart with this script:
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, initial-scale=1.0';
document.body.addEventListener('gesturestart', function () {
viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
}, false);
}
}
Solution 2 - Html
Scott Jehl came up with a fantastic solution that uses the accelerometer to anticipate orientation changes. This solution is very responsive and does not interfere with zoom gestures.
https://github.com/scottjehl/iOS-Orientationchange-Fix
> How it works: This fix works by listening to the device's > accelerometer to predict 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.
Minified source:
/*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT License.*/(function(m){if(!(/iPhone|iPad|iPod/.test(navigator.platform)&&navigator.userAgent.indexOf("AppleWebKit")>-1)){return}var l=m.document;if(!l.querySelector){return}var n=l.querySelector("meta[name=viewport]"),a=n&&n.getAttribute("content"),k=a+",maximum-scale=1",d=a+",maximum-scale=10",g=true,j,i,h,c;if(!n){return}function f(){n.setAttribute("content",d);g=true}function b(){n.setAttribute("content",k);g=false}function e(o){c=o.accelerationIncludingGravity;j=Math.abs(c.x);i=Math.abs(c.y);h=Math.abs(c.z);if(!m.orientation&&(j>7||((h>6&&i<8||h<8&&i>6)&&j>5))){if(g){b()}}else{if(!g){f()}}}m.addEventListener("orientationchange",f,false);m.addEventListener("devicemotion",e,false)})(this);
Solution 3 - Html
Hopefully, this will help ...
<head>
<style type="text/css">
<!--
/*
I began with the goal to prevent font scaling in Landscape orientation.
To do this, see: http://stackoverflow.com/questions/2710764/
Later, I just wanted to magnify font-size for the iPad, leaving
the iPhone rendering to the css code. So ...
(max-device-width:480px) = iphone.css
(min-device-width:481px) and
(max-device-width:1024px) and
(orientation:portrait) = ipad-portrait.css
(min-device-width:481px) and
(max-device-width:1024px) and
(orientation:landscape) = ipad-landscape.css
(min-device-width:1025px) = ipad-landscape.css
*/
@media only screen and (min-device-width: 481px)
{
html {
-webkit-text-size-adjust: 140%; /* none for no scaling */
}
}
-->
</style>
</head>
Solution 4 - Html
The fix used by jQuery mobile is here
https://github.com/scottjehl/iOS-Orientationchange-Fix
Minified
/*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT / GPLv2 License.*/(function (a) { function m() { d.setAttribute("content", g), h = !0 } function n() { d.setAttribute("content", f), h = !1 } function o(b) { l = b.accelerationIncludingGravity, i = Math.abs(l.x), j = Math.abs(l.y), k = Math.abs(l.z), (!a.orientation || a.orientation === 180) && (i > 7 || (k > 6 && j < 8 || k < 8 && j > 6) && i > 5) ? h && n() : h || m() } var b = navigator.userAgent; if (!(/iPhone|iPad|iPod/.test(navigator.platform) && /OS [1-5]_[0-9_]* like Mac OS X/i.test(b) && b.indexOf("AppleWebKit") > -1)) return; var c = a.document; if (!c.querySelector) return; var d = c.querySelector("meta[name=viewport]"), e = d && d.getAttribute("content"), f = e + ",maximum-scale=1", g = e + ",maximum-scale=10", h = !0, i, j, k, l; if (!d) return; a.addEventListener("orientationchange", m, !1), a.addEventListener("devicemotion", o, !1) })(this);
Full source
/*! A fix for the iOS orientationchange zoom bug.
Script by @scottjehl, rebound by @wilto.
MIT / GPLv2 License.
*/
(function(w){
// This fix addresses an iOS bug, so return early if the UA claims it's something else.
var ua = navigator.userAgent;
if( !( /iPhone|iPad|iPod/.test( navigator.platform ) && /OS [1-5]_[0-9_]* like Mac OS X/i.test(ua) && ua.indexOf( "AppleWebKit" ) > -1 ) ){
return;
}
var doc = w.document;
if( !doc.querySelector ){ return; }
var meta = doc.querySelector( "meta[name=viewport]" ),
initialContent = meta && meta.getAttribute( "content" ),
disabledZoom = initialContent + ",maximum-scale=1",
enabledZoom = initialContent + ",maximum-scale=10",
enabled = true,
x, y, z, aig;
if( !meta ){ return; }
function restoreZoom(){
meta.setAttribute( "content", enabledZoom );
enabled = true;
}
function disableZoom(){
meta.setAttribute( "content", disabledZoom );
enabled = false;
}
function checkTilt( e ){
aig = e.accelerationIncludingGravity;
x = Math.abs( aig.x );
y = Math.abs( aig.y );
z = Math.abs( aig.z );
// If portrait orientation and in one of the danger zones
if( (!w.orientation || w.orientation === 180) && ( x > 7 || ( ( z > 6 && y < 8 || z < 8 && y > 6 ) && x > 5 ) ) ){
if( enabled ){
disableZoom();
}
}
else if( !enabled ){
restoreZoom();
}
}
w.addEventListener( "orientationchange", restoreZoom, false );
w.addEventListener( "devicemotion", checkTilt, false );
})( this );
Solution 5 - Html
This seems to be a bug in iOS 4 which can be remedied with the following Javascript snippet, however it disables the user's ability to do pinch-to-zoom:
https://gist.github.com/901295/229d163414e22ebb14a6a6ba0b9777118f02e52d
Solution 6 - Html
This one works !
<script >
// BUG orientation portrait/lanscape IOS //
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, initial-scale=1.0';
document.addEventListener('orientationchange', function () {
viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1';
}, false);
}
}
</script>
Solution 7 - Html
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
Solution 8 - Html
When you say it scales the page up, is that all elements, or just the text font size?... For fixing the font size you can use:
html {
-webkit-text-size-adjust: 100%;
}
Solution 9 - Html
I came up with a different solution to keep the zoom at 1 on rotation, but allow the user to pinch-to-zoom. Basically when the user zooms, javascript changes the viewport zoom level (and the native browser zoom functionality is disabled).
See it here: https://stackoverflow.com/a/11878932/436776
Solution 10 - Html
The first fix worked for me with the following changes.
Change initial scale to .8, minimum to .25 and maximum to 1.6.
Use the "meta" tag
<meta name="viewport" content="width=device-width, initial-scale=1">
<script ="text/javascript">
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=.25, maximum-scale=1.6, initial-scale=.8';
document.body.addEventListener('gesturestart', function () {
viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
}, false);
}
}
Solution 11 - Html
to meta:
%meta{content: "width=device-width, initial-scale=1.0, minimum-scale=0.25, maximum-scale=1.6, user-scalable=yes", name: "viewport"}
to global script:
if navigator.platform.toLowerCase() is "ipad"
viewport = $ "meta[name='viewport']"
viewport_content = viewport.attr("content")
# reset initial zoom
viewport.attr "content", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes"
setTimeout =>
viewport.attr "content", viewport_content
, 0
# reset zoom on rotate
timeout = null
window.onorientationchange = ->
clearTimeout timeout if timeout?
viewport.attr "content", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes"
timeout = setTimeout =>
viewport.attr "content", viewport_content
, 1000