Responsive Images with PHP and jQuery
Responsive Web Design is quite a hot topic at the moment and I'm only just starting to dip my toe in the area. It started gaining popularity with the Responsive Web Design article from A List Apart Article by Ethan Marcotte who has a book pending on the subject by A Book Apart. I'll definitely pick up a copy when it's released on the 7th June as the other books in the publishing series are useful and great to have on the shelf.
The main crux of Responsive Web Design is using CSS media queries to switch the layout depending on the screen size. A site can be optimized and look great on a mobile device, a tablet and on a PC without affecting content or by crazily creating subdomains for mobile only versions of the site. In this article I'm going to go whizz through the topic and concentrate on responsive images and the solutions currently in place and finally go through my own custom solution using PHP and jQuery.
If all this is new to you take a look at a few good resources on the topic:
- handcraftedpixels.co.uk
- netmagazine.com/features/responsive-web-design
- designshack.co.uk/articles/css/20-amazing-examples-of-using-media-queries-for-responsive-web-design
- smashingmagazine.com/2011/01/12/guidelines-for-responsive-web-design
Quite recently a few boilerplate projects have popped up which are a great starting point for any HTML5 project and use media queries by default. These include 320 and up by Andy Clarke (you should follow him on Twitter because he's very funny) who has a great book out at the moment and a more recent one called Skeleton which uses a 960 grid and has other inbuilt styles for buttons, tabs & forms. These are being updated and developed so be sure to check out the projects quite regularly as they're fairly new.
One of the issues that has come to light with Responsive Web Design is the correct use of images, if you're developing for the mobile enviornment some people wont be connected to a fast wifi and so bandwidth is an issue. Currently the popular method when dealing with images is to serve up the highest possible version and reduce the size of the image depending on it's parent container (unstoppablerobotninja.com article). The problem with that is when viewed on a mobile device of 320 or 480 pixels the original image can be quite large (> 100 KB) and when bandwidth is scarse it's going to take a long time to download on mobile devices not connected to wifi.
The "Filament Group" came up with a great solution which serves either a hi or low res image depending on the screen resolution. It works by using an .htacess file to route all image requests to a script which will switch the image. Clever stuff, mobile devices get served the low res version and everyone else gets the hi-res image.
This article will expand on that concept and use a jQuery & PHP solution to automatically resize targetted images to different sizes depending on the size of the browser window.
The HTML
When adding images to resize the first thing we're going to replace is the actual "src" to that it points to a default loading image, this will help speed up the initial page load by not immediately downloading the image. We're also going to supply the real image "src" in the "data-fullsrc" custom html 5 attribute. Add a class name of "resize" to target the image and as a final fallback add a "noscript" tag so that browsers without Javascipt will still get to see the image.
<img src="images/ajax-loader.gif" class="resize js_show loading_image" rel="images/Boston_City_Flow.jpg" /> <noscript><img src="images/Boston_City_Flow.jpg" /></noscript>
An additional class of "js_show" is added so that the image loading image will only be displayed for browsers with Javascript. It will be hidden for non-JS users with the original image being shown instead.
The Javascript
I'm using jQuery here so include that in your source and then include the code below. As an overview the code is looping through all the images that need resizing and firing off an Ajax request to the PHP resize script with the browser width and original image source. The PHP resize script will take the original source, resize it and then return the new location of the image.
function resize_images() {
$('img.resize').each(function(){
var _image = $(this);
$.ajax({
type: "POST",
url: "resize.php",
data: "width="+$(window).width()+"&image="+_image.attr('rel'),
success: function(msg) {
_image.attr('src',msg);
_image.removeClass('loading_image');
}
});
});
}
The PHP
The PHP script will deal with the Ajax request, ensure that the image exists, resize it if necessary and according to the browser width and then spit back the URL so that it can inserted back into the img src attribute by the Javascript file. Download the demo zip file below to look at the source code. For ease I've used the resizer file from the following NetTuts article
Demo & Download
The demo is available online here and the files can be downloaded here
Wrapping Up
I've been really lazy with the blog and not posted anything for ages so getting something new up is quite refreshing, and not CakePHP related either :) Any questions, issues or feedback comment below.
Comments
Woah There (08/06/2011 - 22:36)
Yikes. There are WAAAY too many POST web requests being made in the demo. I'm watching the Firebug Net tab go nuts.
Live resizing is good but there's a better way to optimize that mess: One request to the server per image to get a list of available image sizes. Then let the client-side JS decide which image to show.
James (09/06/2011 - 07:25)
@Woah There: There are quite a few, had trouble getting the resize logic up and running however this is just for demo purposes. On a real site it would just happen once as the script gets the browser size and then displays the optimum image.
Could even do just one request for all images and do them all at once, that would probably be an even better solution.
JDD (08/07/2011 - 17:43)
Great Design. This is pretty slick except for one major flaw! This method does not work in IE period. However that is a Skeleton Boilerplate issue and not reflective of your design.
Matt Wilcox (19/09/2011 - 23:24)
Nice thinking. There are a few stabs at solving this puzzle; have you seen http://adaptive-images.com with another take on it?