77

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?

George Armhold
  • 30,824
  • 50
  • 153
  • 232
  • Good read about it here - https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag#Viewport_width_and_screen_width – vsync Apr 19 '13 at 13:47
  • Just a note - ---key pair separator should be `,` not `;`--- gives a parsing error in Google Chrome (`Error parsing a meta element's content: ';' is not a valid key-value pair separator. Please use ',' instead.`) – Bill Mar 06 '14 at 00:44

9 Answers9

108

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

Tobias Cohen
  • 19,893
  • 7
  • 54
  • 51
  • 5
    It also prevents content from being sized correctly on initial display. If you omit the `initial-scale` element entirely from the viewport tag, HTML content is initially scaled so that it fits entirely in the viewer; with `initial-scale=1.0`, the content is usually wider or narrower than the web view frame. – MusiGenesis Aug 22 '12 at 20:30
  • I have a slighly different approach that should handle it, with a little bit of tweaking so long as you understand the idea of it, http://www.jqui.net/tips-tricks/fixing-the-auto-scale-on-mobile-devices/ – Val Nov 06 '12 at 09:55
18

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.

Matt Lyons-Wood
  • 931
  • 11
  • 17
  • 10
    Preventing user-scaling doesn't stop safari from rescaling on rotation. – Leopd May 16 '12 at 19:39
  • 6
    But why disable zoom? – nroose Oct 18 '13 at 19:42
  • 5
    I hate those mobile websites that disable zooming – Aximili Mar 15 '14 at 04:25
  • @nroose to save 300ms on mobile ? – Guillaume Vincent Oct 21 '14 at 09:57
  • @guillaumevincent Hope you don't ever have the vision problems I have. – nroose Oct 21 '14 at 17:24
  • @guillaumevincent, I can understand trying to save a third of a second on a web-based game or app that is used extensively, but to do it on a news site seems to me just the developer being picky and sacrificing accessibility for the sake of something that users won't notice/appreciate. – nroose Oct 21 '14 at 18:50
  • @nroose if your site/app need zoom on mobile device, maybe it's not well formated ? If you need the zoom, for a special feature, just remove user-scalable=no. With responsive web site we don't need pitch zoom – Guillaume Vincent Oct 22 '14 at 07:21
  • @guillaumevincent the problem for me is that many mobile news sites have this zoom preventer, and the text is a little too small for me. This is because it has become fashionable to prevent zoom for mobile sites, and also has been fashionable to have small print. This creates a problem for me in that it is hard to read. And those sites don't have many links, so the 300ms delay is not meaningful. In these cases, the developer was seeing this performance improvement in many places on the internet and not seeing anything about accessibility. – nroose Oct 22 '14 at 19:09
10

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>
And Finally
  • 5,602
  • 14
  • 70
  • 110
  • Dope! I noticed that I needed initially only set my meta tag with width=device-width and nothing else. Super impressed with this fix. – Shane Feb 13 '14 at 02:37
2

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.

  • Hmm, just tried that and it doesn't seem to have any effect. It's as if the dimensions of the UIWebView are somehow fixed at their portrait orientation dimensions. – George Armhold Aug 07 '09 at 01:41
2

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

Val
  • 17,336
  • 23
  • 95
  • 144
1

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 :)

BadPirate
  • 25,802
  • 10
  • 92
  • 123
0
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1">

suport all iphones, all ipads, all androids.

Piseth Sok
  • 1,789
  • 1
  • 20
  • 24
-1

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 :)

mads
  • 37
  • 1
  • 7
-2

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

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

window.addEventListener('orientationchange', doOnOrientationChange);
ScottC
  • 452
  • 8
  • 25