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.
The beauty of this script is its simplicity. Here’s all you have to do:
imgelements with your lo-res image as the default src
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.
We are using the jQuery selector here but you could just as easily use:
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.
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.
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.
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:
wp_load_imageand assigned to a variable
imagefilterto turn it into a black and white version
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.
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.
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.
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.
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.