Razor-sharp Images in Mobile Safari on iPhone 4

The latest generation of smartphone displays have vastly higher pixel densities than their desktop counterparts–more than double in the case of the iPhone 4’s much vaunted Retina display. The difference is now so large that mobile browsers have been forced to start auto-scaling content, typically rendering a CSS dimension of 1px as two physical screen pixels, in order to keep web content at a readable size.

As long as the desktop rendering of your site is the priority, and desktop display resolutions continue to lag behind smartphones, this auto-scaling will do just fine; however, when customers become more and more accustomed to the razor-sharp detail that can be achieved by using every single pixel of these high-resolution displays, the scaled versions of your site’s graphics will look more and more clunky by comparison.

To make your site look at home on a high-resolution display, you’ll need to create images with twice the pixel dimensions of a desktop version of that same image; for instance, a 32×32 pixel icon on the desktop version of your site will have to be redrawn at 64×64 pixels in order to display at about the same size (but twice the resolution) on the phone. You simply size that image to 32px by 32px in your CSS, and soak up the detail:

.icon {
  background-image: url(icon64x64.png);
  width: 32px;
  height: 32px;
}

But wait: an image with twice the resolution will be about four times the file size, and the desktop browser will have to expend significant effort resizing the high-res images to display at half the size. Despite the extra work involved, it’s best to prepare low-res (say 32×32 pixel) and high-res (64×64 pixel) versions of your site’s images, and use a CSS media query to send the high-res images to auto-scaling browsers only:

.icon {
  background-image: url(icon32x32.png);
  width: 32px;
  height: 32px;
}

@media only screen and
    (-webkit-min-device-pixel-ratio: 2) {
  .icon {
    background-image: url(icon64x64.png);
  }
}

Loading high-resolution versions of images in <img> tags is trickier, since you’re unable to control the src attribute with CSS. Sneaky developers have figured out various ways to achieve it, though (for example, having a request for a high-resolution CSS image set a cookie, that then causes the server to send high-resolution content images too).

High-resolution images may seem like a lot of extra work, but the day you see your entire site displayed at twice the resolution that you’re used to, it will all be worth it.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Baba

    or use SVG. Mobile Safari supports it pretty good.

  • ahallicks

    Media queries are starting to feel like the old browser sniffing methods used in JavaScript and CSS < 3. I guess, at least in this case, it's only if you WANT to improve your site for specific vendors, rather than making it work in the first place.

  • Justen

    You may want to consider that you’ve just doubled the image bandwidth requirements for a device that typically has a slower connection speed and a bandwidth cap to contend with. I’m not sure the mobile web *wants* double-resolution images right now.

    Also as Baba pointed out, SVG is our friend when it comes to image scaling issues. With Raphaeljs help we can even call it “tolerant” of everyone’s favorite short-bus browser. Using Raphael + SVG may increase the payload if you’re just changing a logo but should balance out with anything larger (I think Raphael compresses to around 2kb).

    I also agree with ahallicks about media queries; I can’t help think they’re becoming css hacks rather than real solutions, especially the way we’re using them.

    Nonetheless, thanks for the tip, I’m sure it’ll come in handy at some point. I know I have some issues with a site on iPhone in portrait mode that this kind of solution might help with :)

    • JAS

      Media queries are brilliant allowing you to make your semantic html file optimized on mobile devices without having to produce an extra html file.

  • http://www.purplespider.co.uk jcwacky

    I’m struggling to understand why this is a problem on the iPhone 4. iPhones and iPads don’t normally display websites at a 1:1 ratio due to the screen size. Users are used to the web sites being “shrunk” to fit on the whole screen and then zooming in to various zoom levels as nessecary.

    The only time I can see this problem appearing is when designing a website to specifically fit on an iPhone display. Such as mobile versions of the site, which are designed not to have to zoom in and out of.

    Is this correct? Do I not need to worry about this for normal websites?

  • Richard Kimber

    Hi,
    I can’t get this to work. The 64 pixel version just appears twice the size as the 32 pixel version.
    What am I doing wrong? Is it possible that you could post an example?
    My markup:
    <!DOCTYPE html>
    <html>
    <head><title>
    Pixel
    </title>
    <style type="text/css">
    .icon, .icon-single {
    background-image: url(/content/images/200.png);
    width: 200px;
    height: 200px;
    }

    .background {
    background: red;
    }

    @media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .icon {
    background-image: url(/content/images/400.png);
    }

    .background {
    background: blue;
    }
    }
    </style>
    </head>
    <body>
    <div class="background">
    <p>
    test</p>
    </div>
    <div class="icon-single">
    </div>
    <div class="icon">
    </div>
    </body>
    </html>
    Rich

  • Richard Kimber

    If I understand your example correctly, I believe you have missed a line out on your example:

    background-image: url(icon64x64.png);
    –> background-size: 32px 32px;

    Rich

    • http://warriorstrong.com Rob Cortez

      This is definitely missing. Without this, the above example will not work. It will just display the background image at double the size.

      Thanks, Rich.