SOS

Shane O'Sullivan's technical blog… really ties the room together

Dynamically change deviceDpi on iOS

Posted by Shane O'Sullivan on December 13, 2011

When Apple released the iPhone 4 with a retina display, they quadrupled the pixel density.  This caused problems for websites, as all their assets would now look tiny.  To solve this, Apple made it so that websites would keep the old low density rather than the retina display, and would allow sites to opt in to using the hi-res display.

This is done by adding a <meta> tag to the header, like

  <meta name=”viewport” content=”initial-scale=0.5,maximum-scale=0.5,user-scalable=no,width=device-width,height=device-height,target-densityDpi=device-dpi” />

Note the 0.5 for the scale values.  This resizes the screen to take advantage of the full retina display.  Pretty.  To use the low-res version, the scale parameters are 1.

However, if you’re writing a static HTML based web app, with no backend, you can’t go sniffing the user agent to figure out whether to set the scale to 0.5 or 1 before generating the page, so you’ll have to do it in JavaScript.

Code!!

Here’s a simple script to do that, from my colleagues on the JSGameBench project at Facebook.  To use this, first put the meta tag above into the <head> of your document, with scale values of 1.

  if (window == window.top) {
        var meta_viewport = document.querySelector &&
          document.querySelector(“meta[name=viewport]“);
        if (meta_viewport && window.devicePixelRatio >= 2 ) {
          meta_viewport.setAttribute(‘content’, ‘user-scalable=no, width=device-width, height=device-height, initial-scale=0.5, maximum-scale=0.5′);
        }
  }

The script looks for the meta tag, checks if you have a hi-res Apple display, and switches the device screen scale to use all the pixels, not just one in four.

One more thing…..

If your web app uses CSS like

html, body {
  width: 100%;
  height: 100%;
}

to fit the app to the screen dimensions, and inside perhaps you have some JS based scroller, then you’ll need two further lines.  The script then becomes

if (window == window.top) {
  var meta_viewport = document.querySelector &&

    document.querySelector(“meta[name=viewport]“);
  if (meta_viewport && window.devicePixelRatio >= 2 ) {
    meta_viewport.setAttribute(‘content’, ‘user-scalable=no, width=device-width, height=device-height, initial-scale=0.5, maximum-scale=0.5′);
    document.body.style.width = ‘200%';
    document.body.style.height = ‘200%';
  }
}:

Without these extra lines, the page will only occupy one quarter of the screen, rather than all of it.

Now you have an app that looks right on older iOS devices, but still uses the hi-res screen of the iPhone4 for really sharp fonts and more.

Finally

Make sure that when designing your borders and other screen elements to use multiples of two.  E.g. have your borders be 2px, not 3px, so that when the phone divides them by two it’ll look right.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 535 other followers

%d bloggers like this: