<meta name="viewport">

I spend some time recently fiddling around with meta viewport, so I'll share some notes. First here are the specifications:

The blog posts A pixel is not a pixel is not a pixel and The two viewports are good to read describing the "problem" with zooming and viewport. The trouble is that high dpi mobile devices are zooming in by default. Speciality of the iPhone is that the user-agent string is totally the same for 320px iPhone 3 as for the iPhone 4 which is 640px wide. To get the nice sharp images on an iPhone 4 one needs to use 640px images and set the image width attribute to 100%. At my $work we resize images to exact size of the mobile devices. With this auto-zooming features of modern devices the life's getting more difficult.

And here is what I found regarding the <meta name="viewport"> tag. This are two+1 generally usable examples:

<meta name="viewport" content="width=device-width, minimum-scale=0.5, maximum-scale=1.0,
    user-scalable=no, target-densitydpi=device-dpi"/>
<meta name="viewport" content="width=device-width, minimum-scale=0.5, maximum-scale=3.0,
    user-scalable=yes, target-densitydpi=device-dpi"/>
<meta name="viewport" content="width=640,          minimum-scale=0.5, maximum-scale=3.0,
    user-scalable=yes, target-densitydpi=device-dpi"/>
  • width=device-width will tell the browsers to use the native resolution of the phone.
  • target-densitydpi=device-dpi is needed for the phones with Android and a high-resolution (or high-dpi, example screens with 480x800, like Samsung Galaxy S) to not zoom. Note that the target-density is at the end of the content attribute. This is because it is unrecognised by iPhone and if iPhone encounters and unrecognised option in the viewport content attribute it stops parsing and will ignore the rest of the string.
  • maximum-scale=1.0 together with user-scalable=no is there to forbid zooming in. If the page is optimized for the mobile resolution it's ok to disable it.
  • maximum-scale=3.0 together with user-scalable=yes can be used to let the freedom to the users to make the fonts/links/images bigger. Just one note here. Once the user applies his own zoom on the page there is no way with JavaScript to get the native screen resolution.
  • minimum-scale=0.5 is a little bit tricky. The 0.5 is there for the iPhone 4. This device under normal conditions is rendering images 320px wide to the full screen width, which means zooming them in => 320px images is shown on the full width of 640px wide screen. I found just one way to force iPhone 4 to show 640px images natively (without width attribute) and that is to set width=640 in the viewport meta tag. The problem is that the only way to recognize iPhone 3 from iPhone 4 is via JavaScript and window.devicePixelRatio == 2. But the JavaScript is a little bit too late for the content of the page.
  • width=640 setting the proper (fixed) width is also necessary for the windows mobile phones with IE in order to have the native resolution.

This is not all. There are device databases (WURFL, DeviceAtlas) that collect user-agent strings and helps to provide screen widths to the mobile page rendering engines, but for an Opera Mini & Opera Mobile the user-agent string is the same/similar for all kinds of devices. And the change of device orientation is also worth to consider, as just by turning the phone around, width of the screen changes from 480px to 800px.The only way to get the screen resolution is in JavaScript, but that is too late, the page is already there...

One solution I've described in the beginning and that is to let the browser scale down the high-resolution pictures. This works for the modern phones and is not too bandwidth friendly (providing 640px wide images to all types of phones) and not so reliable with the old phones either. Another solution, that I'm testing currently, is to try to guess the screen width as good as possible based on user-agent string and then use JavaScript to get the proper screen width, reloading the page with a cookie set if necessary (if the width is not what was expected) or having the proper width set for the next page request.

One final thought - Why don't the mobile browsers send the display width and height in the http headers? This will save us a lot of troubles with device detection.