Retina Display and high-definition embeded media
You can use CSS media queries to detect high definition displays and trigger the browser to use high-definition artwork. But there are no HTML attributes to do the same for image-replaced elements within the mark-up. We need a solution.
Traditional displays vs High Definition displays
New displays such as Apple’s iPhone 4 Retina technology offer extremely high resolutions, making text and images far sharper to applications created with high-density displays in mind. That’s great for everyone, but has a few practical knock-on’s for us web designers.
Traditionally websites could be thought of as mapping a CSS pixel unit to a physical pixel on the display, meaning that declaring a 1px value in CSS effected a single physical pixel on the screen. That assumption, although logical, is not technically how CSS works. Retina type displays have much smaller physical pixels than traditional displays, and if websites rendered a CSS pixel as a physical pixel on these high-density displays everything would be far too small to read. Which is why a CSS pixel isn’t actually a physical pixel (and never was except through coincidence). Practically, what happens on high-density displays is a “doubling up”, so that a single CSS pixel is actually four physical pixels (two wide and two tall). To take advantage of the high definition display and address physical pixels instead of CSS pixels we must now use CSS media queries.
If you want to learn more about using media queries to target high-definition displays, and of design considerations now that displays are so varied, read the fantastic ALA article by Ethan Marcotte Responsive Web Design.
The problem with how HTML/CSS handles high definition displays
Is simple and fundamental. We can only do fancy media queries for CSS supplied imagery. It only effects the images you define inside your CSS. So, imagine your website is a gallery, and you’vve got a lot of embeded images because they’re content and not decoration - they’re all going to be low-definition. All of the media, be it an
<object /> or whatever, will be low definition - because there’s no way to tell the browser that the resource in question is intended to be rendered as pysical pixels rather than CSS pixels.
Are there solutions?
I’ve not had chance to try as I do not own an iPhone 4, but a theoretical solution would be to load a double size image (a natural 800x800 for example) and add the HTML5 width/height attribute to the image tag, specifying the image to render as half of the real image size. e.g.,
<img src="/my-image-800x800.jpg" height="400" width="400" alt="whatever" />
Whether this works depends on the browser’s rendering engine, and I don’t know for sure - would it downsample the image to 400x400 and map to it’s CSS pixel (which is essentially a grid of four real pixels, and thus lose any of the added resolution), or would it render the real pixels? Sadly I think it’d have to downsample, unless the webkit guys have been smart and can detect the true image dimensions and trigger “high def” rendering appropriately. i.e., when the ratio of real dimension to specified dimension is 2 or greater. The problem with this type of solution is of course the wasted bandwidth on low-definition displays.
Does anyone know if the browser manufacturers have a plan to address this issue?
There’s a simple test to see whether the technique I mention works or not, but as I don’t have an iPhone 4 I can’t test it myself. So, please can you load the test page on your iPhone 4 and let me know if the second and fourth images are sharper and more detailed than the first and third?
As an aside, using the technique does show far more detail in webkit based browsers (even desktop browsers) once the user zooms the page (try cmd + and compare the bottom two images on the test page).