devicePixelRatio

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.

Definition

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.

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.

Browser support

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:

IE and Firefox don’t support the property at all. I assume the next versions will implement it.

Opera desktop on retina devices give 1, while it should be 2. I assume the next Opera version will fix this.

Opera Mobile 10 does not support it, but 12 implements the property correctly.

UC always gives 1, but UC is quite confused when it comes to viewport properties.

MeeGo WebKit (Nokia N9/N950) does something horrible: it changes the value from 1 to 1.5 when you apply a meta viewport.

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 screen.width, too.