A while ago now, I tweeted about using cookies as a means of serving images to a browser based on the size of the device viewport. Scott Jehl has already implemented the idea into a branch of his responsive images script but now that I have a platform to document my ideas I’ve decided to write up my approach to responsive images.
CSS media queries allow us to develop flexible designs that adapt to the device rendering them. Initially designers worked in a “desktop-down” fashion designing for large screen sizes, working down to the smallest. This approach has since been challenged and now projects such as Mobile Boilerplate and ‘320 and Up‘ are encouraging a “mobile-up” approach to design.
When it comes to imagery it doesn’t matter which way you choose to implement responsive design because you’ll always end up with the same problem; the dimensions of the images used in a page will always be dictated by the largest screen resolution you designed for.
This becomes an issue as a design scales down to fit smaller screens. The high resolution image is still downloaded by the browser before it’s scaled down to fit into a smaller space. Not only is this a waste of bandwidth, downloading oversized images can also significantly delay the initial page render time. These issues are compounded if the visitor is browsing over a mobile network.
src attribute of
<img> tags based on the window size of the browser. I have a different approach to solving this problem.
<head> to ensure the cookie is set before any images are requested from the server.
I’m storing the dimensions of the screen rather than the browser window so the server can determine the maximum size an image could be rendered at. I can’t reliably use the dimensions of the browser window because it could start out at relatively small size causing low-res images to be downloaded on a hi-res screen and these images would look terrible if the browser was later increased in size.
Working with the cookie on the server
Now the server is able to detect the dimensions of the requesting device we need a script to act on this information and send back an optimised image. For this example I’m using PHP, the code we need is listed below:
In my website’s ‘images’ folder I created ‘index.php’ and populated it with this code. I also added my high resolution image ‘test.png’ along with two smaller versions named ‘test-med.png’ and ‘test-low.png’, these we will be sent to smaller screens.
And finally we need an html document:
How it works
<img> element. The image points to the ‘index.php’ script, using the query string (the part after the ‘?’) to specify the file name of the required image. The cookie will be set before the image is requested so the screen dimensions of the device will also be passed to the php script.
The php script itself is pretty simple. It checks for the existence of the cookie and sets the
$device_height variables accordingly. If the cookie isn’t set these variables would evaluate to zero causing the script to return the high resolution version of the image. If
$device_width is not zero, the script then determines which image would be appropriate for the screen and, if it exists, returns it to the browser.
I purposely named the php script ‘index.php’ so I can omit it’s name from file references. I also added it to the images folder so I can toggle progressive and non-progressive images by adding / removing the
Are there any caveats?
Yes, but only one. Any images will need to be hosted on a cookie enabled domain.
This technique isn’t limited to
<img> elements. It could be used to serve responsive images to your CSS. In fact, it can be used for much more than serving images – any file requested from the server could, in theory, be responsive.
We could improve this technique further by appending
window.devicePixelRatio to the cookie the php script can detect for HD and Retina displays and serve higher resolution graphics. The php script could also be adapted to automatically scale down images for us.