Four years ago, (eight months before the original iPhone was announced) Dave Hyatt wrote about high DPI web sites on the Surfin’ Safari blog:
One area of Web design that is going to become more important in the coming years is high DPI. For those of us working on WebKit, this will also become an issue for WebKit applications and for Dashboard widgets.
The future is now.
The “Retina Display” of the iPhone 4 doubles the pixel density we’re used to seeing on handheld devices and thus drastically improves the sharpness of text on the web. But what about images? In order to preserve the design of existing websites, images are automatically pixel-doubled. And this creates a schism between “device pixels” and “CSS pixels”.
John Gruber’s “Why 960 × 640”:
I don’t think that MobileSafari will be able to continue mapping the “px” unit to physical display pixels, because the disparity between the physical pixel size of old and new iPhones is going to be enormous.
Dave Hyatt again:
Most Web site authors have traditionally thought of a CSS pixel as a device pixel. However as we enter this new high DPI world where the entire UI may be magnified, a CSS pixel can end up being multiple pixels on screen.
For example if I set a zoom magnifcation of 2x, then 1 CSS pixel would actually be represented by a 2×2 square of device pixels.
This is exactly what’s happening on the iPhone 4.
So the question for web developers becomes, how do I update my website’s images with higher resolution versions for high DPI devices? Or better yet, how do I do all that in a way that degrades gracefully?
Apple’s Safari Web Content Guide has long recommended using CSS3 media queries to conditionally include stylesheets for specific device widths. But Hyatt’s post mentions a new feature, device-pixel-ratio, for targeting specific pixel densities.
I tried that new feature out by adding this line to my little mobile website:
<link
rel="stylesheet"
type="text/css"
href="/css/retina.css"
media="only screen and (-webkit-min-device-pixel-ratio: 2)"
/>
This tells browsers to include “retina.css” only if the device pixel ratio is 2 or higher. (The feature seems to only be available via the -webkit extension for now.)
The “retina.css” file overrides the background images of some of my site’s graphics with higher resolution versions and uses the background-size property to set the correct CSS pixel dimensions. (I use Komodo Media’s Social Network Icon Pack and Mark James’ Silk icons for many of the graphics.)
High DPI devices represent an exciting opportunity for web developers to do some amazing things and this example only barely scratches the surface.
Update: I've updated my app to include the media query CSS inline in the main stylesheet.

Pixel doubling is WRONG, we have the DPI parameter and the point unit (pt) for a reason. Pixels have to stay absolute display pixels, you can't just slab layers over layer on top to abstract the original purpose because you used it wrong before... (DPI settings aren't for zooming, if you didn't know)
Posted by: Dorian Muthig | June 24, 2010 at 09:28 PM
Doing anything pixel-based is even wronger. That practice is just an artifact of our very low display resolutions. The faster we get good resolutions, the faster we can leave thoughts about pixels behind, just like we did with printers.
By the way, the old iPhone already did a lot of magic behind the curtains: it reports that its screen is actually 980 pixels wide and then maps those 980 virtual pixels to 320 (portrait) or 480 (landscape) real pixels. And then there's the zooming. So with the iPhone 4 it's actually 980 -> 960 (or maybe they changed the virtual screen size to 960) so it's closer to a 1-to-1 mapping than the older iPhone, so providing higher resolution images to the iPhone 4 than to computer browsers seems strange.
Posted by: Iljitsch Van Beijnum | June 25, 2010 at 02:03 AM
It’s much better to just use inline media queries in your CSS instead of separate files (to save an additional HTTP request)
http://twitter.com/mathias/status/16881506343
Posted by: Mathias Bynens | June 25, 2010 at 05:31 AM
We're all using SVG for our graphics now, so media queries for high-res mobile devices isn't necessary. Right? Right?
Posted by: Chris | June 25, 2010 at 05:47 AM
Stop using px units in CSS! Use points, or even better, use points for your base text size and then ems for images, that way you guarantee the proportion of you images and text will remain the same on any device. Using ems means that when a user alters the text size in their browser settings that the images resize too.
Thanks to the @fontface and other CSS3 attributes we don't need to use images for heading text anymore. For images try to use SVG. Where bitmaps have to be used make sure that they are high resolution and let the browser scale them. They do a much better job of this now than they used to. The magic number used to be 288dpi, as both 96dpi, the assumed resolution of Windows, and 72dpi, the assumed resolution of Mac OS are factors which makes for easy scaling for the browser, even older ones. I've been building websites this way since CSS1 made it all possible.
The iPhone 4 display is slightly higher at 326dpi. I don't know how well the device will scale up.
The px unit should only ever be used to get hairline width lines with a constant 1px weight.
Posted by: Tim | June 25, 2010 at 06:58 AM
Tim: the DPI is meaningless on the web, unless you know both the absolute size of the screen and its resolution. But you never want an image to have the same absolute size on both a large monitor and the iPhone's screen. What you want is the same relative size: half the browser window on the computer vs half the screen on the iPhone. In both cases that could be about 500 pixels, but you never know.
Also, scaling algorithms used by today's browsers are advanced enough that there's really no penalty for using fractional factors rather than 2 or 4 x. So something in the neighborhood of 12 pixels/mm (300 DPI for those still living in the imperial dot-based world) should be fine for anything photo-realistic.
Posted by: Iljitsch Van Beijnum | June 25, 2010 at 08:22 AM
Umm, Dorian? No, when it comes to CSS a pixel is *not* an single absolute display pixel, and never has been: http://www.w3.org/TR/CSS21/syndata.html#length-units
The spec builders recognized the day of hi-res devices was coming, and built the spec to acknowledge it. What Apple appears to be ignoring is the suggestion by the spec that the user-agent automatically do the conversions.
Posted by: Arlen | June 25, 2010 at 11:39 AM
gee - if only we could use Flash we'd have vector graphics... oh well.
Posted by: bobthebob | June 26, 2010 at 02:22 PM
I'm confused. A pixel measurement is still a pixel though, right? If you have an html element of x pixels, and an image of x pixels, they still appear the same size on screen, yes? Otherwise, that'd be stupid.
Posted by: James | June 28, 2010 at 07:39 AM
@bobthebob → SVG = vector, no need for Flash.
Posted by: Mig Reyes | June 30, 2010 at 08:26 AM
James.. A pixel is always a pixel, but it is never an absolutely size.. For instance you can say that a centimeter is actually .4" so there is a finite size.. It will aways be exactly .4" or 1 centemeter.
HOWEVER, i a pixel is not always .5 centemeters... On different displays the size of the pixel is different based on the DPI and resolution and all of that jazz. I dont know enough about DPI and resolution and how monitors map that stuff to comment..
But a pixel is NOT a measurement and is not always the same size.
Posted by: Lindsay | July 05, 2010 at 03:01 PM
Got to agree with Mig, SVG is also vector. We don't need Flash in iPhone 4.
Posted by: Patrick Garde | August 13, 2010 at 11:23 AM