Keir Whitaker


As well as publishing here I also contribute to other online publications — you can find a full list on my writing page. You can also browse the cities, design, ecommerce, events, life, podcasting, travel, web, and work categories and subscribe for updates via RSS or my email newsletter.

Automatic Responsive Images in WordPress

Thursday 12 April 2012

Automattic Responsive Images
Automattic Responsive Images

NB: This article was originally posted to the Viewport Industries blog which, along with the company, is no longer active. This is just one approach that worked well a couple of years ago. Some of the ideas explained here, especially around manipulating images in WordPress are still relevant but with the advancement of the picture element and srcset there are plenty of other options open to help serve images in a responsive setting.

As mentioned in our first post (now offline) we wanted to try out a few relatively new techniques on this (the Viewport Industries) site, the main one being the inclusion of Josh Emerson’s Responsive-Enhance script to serve responsive images.

The simplest way to see the script in action (if you are using a desktop browser) is to resize this screen so that it’s very narrow and hit refresh; all being well the image above should turn into a black and white version, physically smaller in terms of dimensions and file size. Now slowly stretch the screen out again and you should see the colour version kick back in. Josh’s script cleverly replaces the lo-res version with the full size colour version — nice and easy.

Getting it to Work

The beauty of this script is its simplicity. Here’s all you have to do:

  1. Include a link to the script in your document
  2. Create the relevant img elements with your lo-res image as the default src
  3. Add a data attribute called ‘data-fullsrc’ which has a path to your full size image
  4. Include a call to the responsiveEnhance function in a linked JavaScript file passing in the img element and the screen width to trigger the replacement

Setting it Up

Sounds easy and it is. Here’s how our img element looks with the addition of the required data-fullsrc attribute:

<img id="digest-header" src="<?php bloginfo('template_directory'); ?>/img/heading-digest.gif" data-fullsrc="<?php bloginfo('template_directory'); ?>/img/heading-digest-large.jpg" alt="Digest logo" />

In case you’re not familiar with WordPress, the <?php bloginfo('template_directory'); ?> will be replaced by the current themes directory path.

You’ll notice that this example has an id of ‘digest-header’ — we’ll need this to call the function in our JavaScript in the next step. In order to activate the script we need to call the responsiveEnhance function as follows:

responsiveEnhance($('#digest-header'), 400);

We are using the jQuery selector here but you could just as easily use:

responsiveEnhance(document.getElementById('digest-header'), 400);.

The function takes the img element and the screen width as arguments. It’s that simple. You can also get it working quite easily for images that use a particular class or are contained within a particular section. For example, using jQuery, you could do something like:

responsiveEnhance($('article img'), 400);

This would run the script over all the images contained within an article element.

Automagic Black and White

Setting it up for the home page was simple enough, but having fallen for the technique we wanted our blog header images to follow suit. Hand crafting different versions of the header image for each blog post would result in a lot of work (for Elliot!), so we initially avoided the idea. However, on closer inspection it turned out that we could auto-generate these images using a couple of handy WordPress filters and some (new to me) PHP functionality.

At this point a rather large hat tip must be doffed to c.bavota, whose script got me on the right path. The one I actually use is virtually identical apart from a line or two to handle file naming conventions.

We have created a gist over on GitHub so you can grab the function for yourself. The embed doesn’t currently play that nice with our design so have a quick look and head back for a quick explanation.

The first thing to note is the following function call:

add_image_size('thumbnail-bw', 400, 0, false);

This tells WordPress to create a new image with a name of ‘thumbnail-bw’ at 400px wide for every image that we upload, providing it is 400px or wider. The final two arguments dictate height and crop. In this case we don’t specify a height as we want it sized proportionally, and for crop we specify false which equates to ‘soft proportional crop mode’. With that set up we can go about manipulating our new ‘thumbnail-bw’ image.

WordPress Filters

Next you will notice the add_filter('wp_generate_attachment_metadata','bw_images_filter'); function. A filter is described as follows in the WordPress codex:

Filters are functions that WordPress passes data through, at certain points in execution, just before taking some action with the data (such as adding it to the database or sending it to the browser screen). Filters sit between the database and the browser (when WordPress is generating pages), and between the browser and the database (when WordPress is adding new posts and comments to the database); most input and output in WordPress passes through at least one filter. WordPress does some filtering by default, and your plugin can add its own filtering.

Essentially what filters allow us to do is modify ‘stuff’; i.e.: text or, in our case, images. There’s so much you can do with filters, but that’s another post entirely.

So by filtering the creation of the meta data (every image has associated data that we can use in a variety of WordPress functions in the database) associated with an image we can create our own black and white version for use with our responsive image script.

Our bw_images_filter does all the heavy lifting for us and is called every time wp_generate_attachment_metadata an image is uploaded. Without going into too much detail, here’s what happens in the function:

  • The function receives an array of file meta data relating to our most recently uploaded image. This is passed in from our filter call. This array contains all the details we need to start manipulating our image.
  • Next the image is grabbed using wp_load_image and assigned to a variable
  • The function then runs the image through the native PHP function imagefilter to turn it into a black and white version
  • We then save out the modified version and change the file name by adding the appropriate extension with the -bw suffix, e.g.: filename-bw.png. It’s worth noting that the originally uploaded image will remain on your file system, but you could easily modify the function to delete it.
  • Finally we return the new meta data, which WordPress adds back to the database

It’s a pretty simple function but does the job well. This only works on new uploads but you could modify this function to iterate over your existing files without too much trouble.

Template Logic

Your needs will dictate what kind of logic you employ in your archive or single template. Whilst I have included links below to the loop logic we use on this site as well as the JS function call, I doubt a simple copy and paste will work on most sites. However, simple modifications to relevant class names should be pretty straightforward.

Final Thoughts

Undoubtedly the way we deal with images and responsive design will change in the next few months, but we are very happy with this approach. It works well, is easy to integrate into WordPress, and allows us to have a bit of fun with making them black and white.

I hope it hasn’t been too hard to follow. If you have any questions please feel free to drop a comment below.

Update – August 2012

We removed the black and white element of this script in version 2 of this web site. The principal remains the same but if you resize the browser and refresh you will now see a smaller full colour version of the image. Apologies to those who read this, resized and thought that it wasn’t working.

You can follow Keir on Twitter & Instagram. For updates subscribe to the RSS feed and newsletter.

Subscribe to my newsletter for a weekly round up of new articles, podcasts, links, tips, tricks, apps, products, books, magazines and more.