How to set viewport meta for iPhone that handles rotation properly?

So I've been using:

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;"/>

to get my HTML content to display nicely on the iPhone. It works great until the user rotates the device into landscape mode, where the display remains constrained to 320px.

Is there a simple way to specify a viewport that changes in response to the user changing the device orientation? Or must I resort to Javascript to handle that?

180194 次浏览

You're setting it to not be able to scale (maximum-scale = initial-scale), so it can't scale up when you rotate to landscape mode. Set maximum-scale=1.6 and it will scale properly to fit landscape mode.

Was just trying to work this out myself, and the solution I came up with was:

<meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />

This seems to lock the device into 1.0 scale regardless of it's orientation. As a side effect, it does however completely disable user scaling (pinch zooming, etc).

For anybody still interested:

http://wiki.phonegap.com/w/page/16494815/Preventing-Scrolling-on-iPhone-Phonegap-Applications

From the page:

<meta name="viewport" content="user-scalable=no,width=device-width" />

This instructs Safari to prevent the user from zooming into the page with the "pinch" gesture and fixes the width of the view port to the width of the screen, which ever orientation the iPhone is in.

I had this issue myself, and I wanted to both be able to set the width, and have it update on rotate and allow the user to scale and zoom the page (the current answer provides the first but prevents the later as a side-effect).. so I came up with a fix that keeps the view width correct for the orientation, but still allows for zooming, though it is not super straight forward.

First, add the following Javascript to the webpage you are displaying:

 <script type='text/javascript'>
function setViewPortWidth(width) {
var metatags = document.getElementsByTagName('meta');
for(cnt = 0; cnt < metatags.length; cnt++) {
var element = metatags[cnt];
if(element.getAttribute('name') == 'viewport') {


element.setAttribute('content','width = '+width+'; maximum-scale = 5; user-scalable = yes');
document.body.style['max-width'] = width+'px';
}
}
}
</script>

Then in your - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method, add:

float availableWidth = [EmailVC webViewWidth];
NSString *stringJS;


stringJS = [NSString stringWithFormat:@"document.body.offsetWidth"];
float documentWidth = [[_webView stringByEvaluatingJavaScriptFromString:stringJS] floatValue];


if(documentWidth > availableWidth) return; // Don't perform if the document width is larger then available (allow auto-scale)


// Function setViewPortWidth defined in EmailBodyProtocolHandler prepend
stringJS = [NSString stringWithFormat:@"setViewPortWidth(%f);",availableWidth];
[_webView stringByEvaluatingJavaScriptFromString:stringJS];

Additional Tweaking can be done by modifying more of the viewportal content settings:

http://www.htmlgoodies.com/beyond/webmaster/toolbox/article.php/3889591/Detect-and-Set-the-iPhone--iPads-Viewport-Orientation-Using-JavaScript-CSS-and-Meta-Tags.htm

Also, I understand you can put a JS listener for onresize or something like to trigger the rescaling, but this worked for me as I'm doing it from Cocoa Touch UI frameworks.

Hope this helps someone :)

You don't want to lose the user scaling option if you can help it. I like this JS solution from here.

<script type="text/javascript">
(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) {
fix();
scales = [.25, 1.6];
doc[addEvent](type, fix, true);
}


}(document));
</script>

I have come up with a slighly different approach that should work on cross platforms

http://www.jqui.net/tips-tricks/fixing-the-auto-scale-on-mobile-devices/

So far I have tested in on

Samsun galaxy 2

  • Samsung galaxy s
  • Samsung galaxy s2
  • Samsung galaxy Note (but had to change the css to 800px [see below]*)
  • Motorola
  • iPhone 4

    • @media screen and (max-width:800px) {

This is a massive lip forward with mobile development ...

just want to share, i've played around with the viewport settings for my responsive design, if i set the Max scale to 0.8, the initial scale to 1 and scalable to no then i get the smallest view in portrait mode and the iPad view for landscape :D... this is properly an ugly hack but it seems to work, i don't know why so i won't be using it, but interesting results

<meta name="viewport" content="user-scalable=no, initial-scale = 1.0,maximum-scale = 0.8,width=device-width" />

enjoy :)

<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1">

suport all iphones, all ipads, all androids.

Why not just reload the page when the user rotates the screen with javascript

function doOnOrientationChange()
{
location.reload();
}


window.addEventListener('orientationchange', doOnOrientationChange);