I did some research around the
window.devicePixelRatio property that all WebKit browsers, as well as Opera, support, and for once the news is good. This property’s definition makes sense, and it is implemented almost universally.
Let’s start with a definition:
window.devicePixelRatio is the ratio between physical pixels and device-independent pixels (dips) on the device.
window.devicePixelRatio = physical pixels / dips
Dips are the abstract pixels that are used to feed information to the width/height media queries and the meta viewport device-width. They are best explained by taking a look at the difference between retina and non-retina devices.
All non-retina iPhones have a width of 320 physical pixels in portrait mode. When you use
<meta name="viewport" content="width=device-width"> it sets the width of the layout viewport to 320px, so that the page naturally fits into the screen.
Thus, on non-retina iPhones there are 320 physical pixels and also 320 dips. Thus
<window.devicePixelRatio> equals 1.
Retina iPhones have a width of 640 physical pixels in portrait mode. Still, websites that use the meta viewport should not become 640px wide, but instead remain at 320, which is the optimal reading size for the iPhone.
Thus the number of dips is still 320, even though the number of physical pixels is 640.
window.devicePixelRatio now equals 2.
It pleases me to inform you that most browsers implement
window.devicePixelRatio correctly. The property contains the ratio between physical pixels and dips, and even though some values appear strange at first, they actually make sense.
For once it’s more efficient to give you a list of browsers that do not implement
window.devicePixelRatio correctly. They are:
That’s the bad news. The good news is that Safari, Android WebKit, Chrome 22+ and on Android, Opera Mobile, BlackBerry WebKit, QQ, Palm WebKit, and Dolfin implement the property correctly.
Granted, most of these browsers still run on systems where the value should be 1, so they may run into problems later on, when they move onto a retina-like device.
Two more notes: MeeGo WebKit’s idea of changing the value when a meta viewport is applied is atrociously wrong. First of all the pixel ratio does not actually change when applying a meta viewport: the number of physical pixels and dips stays exactly the same, so their ratio does, too.
Secondly, some browsers make a habit of changing all kinds of stuff when a meta viewport is applied (Samsung Dolfin is a notorious case), and that does not make any sense at all. The only thing that changes when you apply a meta viewport is the dimensions of the layout viewport. If a browser changes anything else, it’s totally wrong and should be laughed out of business.
I wrote a second article about
devicePixelRatio that gives some more details and looks at
Upcoming speaking gigs: