One line of JavaScript and a few mod_rewrite rules and we have no fuss Automatic Conditional Retina Images. No DOM crawling. No redundant requests. No server-side scripts. No cookies? No problem, they just get the original image. The only change you might need to make to your workflow is explicitly defining image width
and height
in HTML (you should really be doing this already) and background-size
in your CSS. And of course, creating retina images. If your original image is named circle.png
the retina version should be [email protected]
If you forget a retina image the original image will be served, even on retina devices. Check the caveats.
if((window.devicePixelRatio===undefined?1:window.devicePixelRatio)>1) document.cookie='HTTP_IS_RETINA=1;path=/';
I think this must be placed inline in the head
(not included in an external JavaScript file) and before any external CSS or images in order for the cookie to be set before any images are requested but I'd be happy to be wrong. Add it to a template or at the very least use some sort of server-side include in case you need to update this in the future.
Add this to an .htaccess
file in the directory where you keep your images:
<IfModule mod_rewrite.c> Options -MultiViews RewriteEngine on RewriteCond %{HTTP_COOKIE} HTTP_IS_RETINA [NC] RewriteCond %{REQUEST_FILENAME} [email protected] RewriteRule ^(.*)\.(gif|jpg|png)$ [email protected].$2 # if @2x isn't available fulfill the original request RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)@2x\.(gif|jpg|png)$ $1.$2 </IfModule>
Be sure to specify width and height of the original (non-retina) image. eg.
<img src="circle.png" width="240" height="240" alt="">
Be sure to specify the background-size
property using the width and height of the original (non-retina) image. eg.
background-image:url(circle.png); background-size:240px 240px;
Lots of reports of future browsers preloading images before the cookie can be set. I'm not seeing this on the iPad 3, 4th generation iPod touch, or the retina MacBook Pro, which are my current primary concerns but I respect they may not be yours. Apparently IE9 does not block while it processes inline JavaScript (currently moot since it doesn't run on a retina device). Firefox 14.0.1 on a retina MacBook Pro does not load the @2x images because it does not support window.devicePixelRatio
and checking min-resolution
with window.matchMedia().matches
seems wonky.