Sunday, May 09, 2010

Customize Android Browser Scaling with target-densityDpi

It was hard to find this little gem, so I thought I'd share it with the world: the Android team has implemented a custom meta viewport property to allow you to customize browser scaling for high resolution (HDPI) screens, like the WVGA 480x854 Motorola Droid and 480x800 Nexus One. [This is as opposed to medium resolution (MDPI) HVGA 320x480 T-Mobile G1 or myTouch 3G.]

You can use it like this, for example: <meta name="viewport" content="width=device-width, target-densityDpi=device-dpi">

What's Browser Scaling?

Here, ppk explains why a pixel is not a pixel. The CSS "px" unit may differ from a device's actual pixels, as the browser "scales" images and fonts to a larger size than you requested. (The browser just naturally assumes you didn't really mean "pixels" when you said "px," and helpfully tries to resize your content to make it readable on high-resolution phone screens.)

The Nexus One and Motorola Droid (and any other WVGA devices) will scale pixels even if you use the <meta name="viewport"> tag to instruct it not to do this. Worse, they using a non-integer scaling factor (e.g. 1.5x zoom, to scale 320px to 480px) which makes images look really weird.

target-densityDpi to the rescue!

Use this new undocumented <meta name="viewport"> property: target-densityDpi. The only existing documentation is in the Android check-in comment:

Add dpi support for WebView.

In the "viewport" meta tag, you can specify "target-densityDpi".
If it is not specified, it uses the default, 160dpi as of today.
Then the 1.0 scale factor specified in the viewport tag means 100%
on G1 and 150% on Sholes. If you set "target-densityDpi" to
"device-dpi", then the 1.0 scale factor means 100% on both G1 and Sholes.

Implemented Safari's window.devicePixelRatio and css media query

So if you use "device-dpi" and modify the css for font-size and image
src depending on window.devicePixelRatio, you can get a better page on

Here is a list of options for "target-densityDpi".

device-dpi:    Use the device's native dpi as target dpi.
low-dpi:       120dpi
medium-dpi:    160dpi, which is also the default as of today
high-dpi:      240dpi
<number>:      We take any number between 70 and 400 as a valid target dpi.

Fix http://b/issue?id=2071943

So how do I use it?

Like this, for example: <meta name="viewport" content="width=device-width, target-densityDpi=device-dpi">

You may also want to add the "user-scalable=no" property to prevent the user from zooming in/out and to guarantee that your images are exactly as you designed them. You can read more about other viewport properties in Apple's documentation which originally defines the