Responsive layouts with ExpressionEngine

In July I wrote about an idea I had about serving responsive images with ExpressionEngine, dynamically delivering images sized appropriately for the device on which they're being viewed, i.e. small images for mobile devices and larger ones desktop computers.

Most of the solutions that had come to light at that time involved detecting the user's screen size on the client side and then manipulating images based on that. To me, that concept didn't seem to work too well if you were using your CMS to dynamically serve up differently-sized images from the same source file. I thought there needed to be some sort of server-side involvement so that information could be passed to templates and then processing carried out appropriately. Some time after I published my post, Luke Wroblewski discussed the same sort of thing and dubbed the process RESS: Responsive Design + Server Side Components.

The idea I had originally was to use PHP to carry out device detection, AKA user agent (UA) sniffing, and then set a variable based on whatever value was returned. There are a couple of problems with that approach:

  1. As Jeremy Keith pointed out, UA sniffing can result in false positives and missing out devices not included in the device detection script.
  2. Once you've detected the device, you then need to set another variable for its size. If you want to cover a lot of devices/sizes, you have to set your script up to set a lot of variables, rather than the size variable being set dynamically as is the case when you use javascript on the client side.

So ideally, you want a combination of both client side to dynamically detect the screen size, and then server side to set that as a variable which can be accessed in your templates.

Just a day after I posted my previous article on the subject, Matt Wilcox wrote about a technique that has now become Adaptive Images, and was recently featured in 24 Ways. The basic idea is you use javascript to set a cookie and then use PHP to access that value and serve up appropriately sized images. A couple of months later and Matt Stauffer took that idea and combined with the concepts that Luke Wroblewski proposed, created a Github project called Simple-RESS, which does exactly what I mentioned above, uses client-side detection to create a server-side variable.

I'm working on a responsive design at the moment and the Simple-RESS technique seemed ideal so I created an add-on based on it (my first attempt at writing an extension too), which you can find on Github. It comprises a plugin which checks if a cookie for the screen size has been set or not, and if not, injects the javascript to do so. (I'm using jQuery to access $(window).width() I was but now I'm not and the Github repo has been udpated. See the changelog for further details.) To do this, you need to add {exp:ress:cookie} somewhere in the <head> of your templates.

With the cookie set, that value is then checked by the extension in the package which sets a global variable {ress} which you can then use in your templates, e.g. { if {ress} > 768}show desktop-only content{/if }. The extension also lets you set a default screen size for those that don't have javascript enabled. What that value should be will depend on whether you want to a take a mobile-first, or desktop-first approach.

This approach is much more flexible than the one I originally proposed because the screen size variable is set dynamically using javascript, rather than having to create a case statement that matches a screen size to every user agent string you want to check for. You can then use the variable with conditionals and case statements in your templates that match up with media queries in your CSS.