37
votes

I have a very simple HTML page with this META tag for the iPhone:

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

Using the iPhone Safari, when the page loads in portrait mode it looks fine and the width fits the screen. When I rotate the iPhone to landscape mode the web page is auto resized to fit the landscape width. Good, this is what I want.

But when I rotate back from landscape, the page is not resized back to fit the portrait width like it was before. It remains in the landscape width.

I want the iPhone to set it back to the right width automatically, just like it did for the landscape mode. I don't think this should involve orientation listeners because it is all done automatically and I don't have any special styling for the different modes.

Why doesn't the iPhone resize the web page back in portrait mode? How do I fix this?

UPDATE

I managed to get the iPhone to auto resize down but with a strange phenomenon of doing it only after an even number of rotations... Very very strange.
I use this META tag:

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

Here's what I have to do to get it auto resized:
1. On load in portrait -> looks good.
2. Rotate to landscape -> resized to fit screen.
3. Rotate back to portrait -> no resize back.
4. Rotate to landscape -> still in size for landscape.
5. Rotate to portrait -> resized down to fit portrait screen.

Can someone explain this behavior??
I still want to know how to fix this and appreciate any assistance.

Thanks!
Tom.

11
##Meta viewport tags do not fix this problem I've tried all of the settings listed and they do nothing to fix the horizontal to vertical resize. I assume jQueryMobile will fix this but as of yet it has the same problem.Scott Romack

11 Answers

31
votes

This has to be a bug in iOS 4 Safari. Here's what my behavior was with the following meta tags (the second tag is to make it full screen):

<meta name="viewport" content="user-scalable=no, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>

Page would scale correctly when going from portrait to landscape until I used the pop up keyboard to enter a value in a field - then it would stop scaling. Which would mean if I used the keyboard in landscape it would be too large when I went to portrait, or vice versa.

Switching using the following meta tags fixed it... Thanks to the other answers on this page.

<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
4
votes

I had the same problem on my 3GS 3.1.3, even though I couldn't get it to ever become the right size again after landscape mode. But when I removed "height=device-height" the page scaled down correctly every time. So my meta looks like this:

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

I'd like to be able to use the height attribute to lock the height, but it seems like they don't mix too well.

3
votes

You need to put one more thing minimum-scale=1.0 so it would like:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" />
2
votes

I'm using ExtJs (sencha touch), it seems Good

Ext.setup({
  tabletStartupScreen: 'images/tablet_startup_768x1004.png',
  phoneStartupScreen: 'images/phone_startup_320x460.png',
  tabletIcon: 'images/tablet_icon_72x72.png',
  phoneIcon: 'images/phone_icon_72x72.png',
  icon: 'images/icon_72x72.png',
  statusBarStyle: 'black',
  glossOnIcon: true,
  fullscreen: true,
  onReady: function() {
    var viewport = null;                                                                                
    var metas = document.getElementsByTagName('meta');                                                  
    for(var i = 0, length = metas.length; i < length; ++i){                                             
      var meta = metas[i];                                                                              
      // already Extjs addedMetaTags                                                                    
      if(meta.name == 'viewport'){                                                                      
        viewport = Ext.get(meta);                                                                       
        break;                                                                                          
      }                                                                                                 
    }                                                                                                   
    if(null == viewport){                                                                               
      viewport = Ext.get(document.createElement('meta'));                                               
    }                                                                                                   

    if(window.navigator.standalone){                                                                    
      // IMPORTANT!!! not set to height=device-height when iphone standalone mode was ignored "scale" settings           
      viewport.set({                                                                                    
        name: 'viewport',                                                                               
        content: 'width=device-width, initial-scale=0.1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'
      });                                                                                               
    } else {                                                                                            
      // IMPORTANT!!! set to height=device-height when !standalone mode; behav window.innerHeight = fullscreen size
      viewport.set({                                                                                    
        name: 'viewport',                                                                               
        content: 'height=device-height, width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'
      });                                                                                               
    } 
  }
});

other devices compatible with ...

var watcher = {
  handlers: [],
  dimentions: {width:0, height: 0},
  fullscreenize: false,
  orientLandscape: function (){
    return 90 === Math.abs(window.orientation);
  },
  orientPortrait: function (){
    return !this.orientLandscape();
  },
  width: function (){
    return this.dimentions.width;
  },
  height: function (){
    return this.dimentions.height;
  },
  changeDimentions: function (evt){
    var self = this;
    (function (){
      if(self.fullscreenize){
        window.scrollTo(0, 1);
      }

      self.dimentions = Ext.Element.getViewSize();
      self.fireOnchange();
    }).defer(100);
  },
  init: function (){
    if('onorientationchange' in window){
      Event.observe(window, 'orientationchange', this.changeDimentions.bind(this));
    } else {
      Event.observe(window, 'resize', this.changeDimentions.bind(this));
    }
    Event.observe(window, 'load', this.changeDimentions.bind(this));
  },
  fullScreen: function (){
    this.fullscreenize = true;
    var self = this;
    document.observe('dom:loaded', function (){
      (function (){
        window.scrollTo(0, 1);

        self.changeDimentions();
      }).defer(100);
    });
  },
  fireOnchange: function(){
    var self = this;
    self.handlers.each(function (handler){
      handler.apply(null, [self]);
    });
  },
  onchange: function (handler){
    this.handlers.push(handler);
  }
};
watcher.init();
watcher.fullScreen();

aComponent = Ext.extend(Ext.Component, {
  initComponent: function (){
    watcher.onchange(this.fullscreen.bind(this));
  },
  fullscreen: function (){
    var height = watcher.height();
    var width = watcher.width();

    this.menu.setHeight(40);
    this.mainPanel.onResize(height - 40, width);
  }
});
1
votes

I also ran into the 'not scaling back when I went back to portrait' problem.

I got it working with

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

for basic scaling back and forth, on 3G with iOS 4, as I change orientation.

I originally used "minimum-scale=1.0", got it to work when I replaced it with "initial-scale=1.0", after I saw the suggestions here.

1
votes

try this <meta name="viewport" content="width=1024" />

1
votes

Just set the viewport directive to...

<meta name="viewport" content="height=device-height, width=device-width, minimum-scale=1.0, user-scalable=yes|no" />

...no need to use JavaScript and you can still allow the user to scale the page should they wish.

0
votes

Are you using XHTML rather than HTML?

Try this, ensuring you close your first meta tag correctly.

<meta name="viewport" content ="user-scalable=no, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
0
votes

This is a bug in Safari on iOS 5 and lower (A.K.A. Safari Viewport Scaling Bug).

Try to avoid fix with meta viewport tags that disables the zoom gesture; instead, use this JavaScript fix:
https://gist.github.com/901295

More info about this bug: http://webdesignerwall.com/tutorials/iphone-safari-viewport-scaling-bug

0
votes

I had the same problem with my iPhone 5. The answer was incredibly simple.

<meta name="viewport" content="width=device-width" />

This properly displays the page in either view, all the time, and offers scalability.

0
votes

We faced the same issue in JQuery Mobile 1.3.0 also, we used the below and it worked

in css

body { /* IOS page orientation change resize issue*/  
  -webkit-text-size-adjust: none ; 
}

and if still the header/footer does not resizes correctly (optional)

$(window).resize(function() { 
   $("div[data-role=header]").width($(window).width());
   $("div[data-role=footer]").width($(window).width());
});