The first few iPhones (and, later, Android phones) all had a screen width of 320 pixels. This prompted web developers everywhere to design mobile sites that were exactly 320 pixels wide.
When Apple introduced the retina display, they doubled the screen width to 640 pixels. Current Android phones go higher than that even. When you view a screen optimized for 320 pixels on a retina iPhone, you could see something like this:
Except that you don’t, of course, most of the time. And that is because of a magic setting called “viewport”. It works like this:
<meta name="viewport" content="width=device-width, initial-scale=1">
The “width” value above can actually be a number of pixels, like “640”. But if you use the special value “device-width”, which almost every mobile page does, crazy adjustments are made. What am I talking about? Read on!
According to Edward Cant:
With the advent of high pixel density displays the pixel itself is now a relative unit.
According to the CSS 2.1 Specification:
Pixel units are relative to the resolution of the viewing device, i.e., most often a computer display. If the pixel density of the output device is very different from that of a typical computer display, the user agent should rescale pixel values.
So, a ‘CSS pixel’ indicates one point on the virtual pixel grid to which our CSS design aligns. This either directly matches the actual device pixel grid on which our content is rendered or it is intelligently scaled.
This has led to the definition of a ‘Density-independent pixel (dip)’. (Android Developers)
A virtual pixel unit that applications can use in defining their UI, to express layout dimensions or position in a density-independent way.
iPhone4 was not the first to employ virtual pixels although other implementations often had less convenient scaling factors. 1 virtual pixel could equal 1.5 physical pixels and so on.
A detailed summary of the ‘Pixel is not a pixel’ situation is available on quirksmode.
If that confuses you, let me simplify: the “pixels” we specify in CSS are not actually hardware screen pixels. They are an abstract grid laid on top of the screen. How wide is that abstract grid? Ah! Now we get to the heart of the matter.
By specifying width=”device-width”, you are asking the browser to apply a scaling factor to its screen pixels. One css pixel occupies one or more screen pixels. How many more? This value is called the css pixel ratio. There is a good list of devices and their css pixel ratios on wikipedia.
If you study that list, you will discover that screen width / css pixel ratio = 320 in most cases. For some Android phones, it comes to 360, a little more breathing room. Bottom line, by specifying width=”device-width”, you transform the browser window into what is effectively a 320 (or so) pixel screen. And now your site that is optimized for 320 pixels looks like this on any phone:
Neat! So as you design mobile sites, you may assume that all phones are 320 pixels wide.
But of course…
The world has moved on. We now use media queries to provide responsive designs across various pixel widths. And we don’t need to punish people with good phones by forcing narrow windows on them. For the modern mobile site, it is better, I think, to omit the viewport width setting, and rely instead on responsive techniques.