Responsive images with WordPress Advanced Custom Fields
Advanced Custom Fields is an amazing (and free) WordPress plugin that turns it into a proper CMS and gives developers fine-grained control over how data entered by content administrators is handled and displayed. I love it.
I also love performant websites ergo responsive images, and I needed to find a way to combine them on a current project. The RICG have been working on a WordPress plugin that creates responsive images from featured image uploads and post content image uploads, but ACF is not core WordPress so misses out.
My aim here was to allow content administrators to only upload one image and the different sized images for
srcset would be created automatically by the CMS. Developer convenience isn’t a consideration, we still need to write the
sizes attributes, this is all about avoiding having to tell our clients to crop an image to different pixel sizes.
Register new image sizes
I initially thought I would have to find a successor to tim thumb but Tom Blanchard pointed me in the direction of the
add_image_size() function on twitter.
For example (somewhat simplified):
add_image_size('blog-small', 200); add_image_size('blog-medium', 600); add_image_size('blog-large', 1000);
This function only creates new images when they are uploaded so if there are any already in the WordPress media library they will need to be regenerated. I used AJAX Thumbnail Rebuild and it worked fine.
Advanced Custom Fields setup
Set up an image field as normal in ACF, the only thing that is slightly different from what I normally do is to set
Image ID as the return value.
To display the different sized images I used the
It takes an image ID and registered size name as parameters, and returns an array containing the image url, width, height and a boolean that indicates if it’s resized or not. We only need the url so to display an image the PHP is:
Extending that to markup:
<?php $img = get_field('image'); ?> <img srcset="<?php echo $img['sizes']['blog-small']; ?> 200w, <?php echo $img['sizes']['blog-medium']; ?> 600w, <?php echo $img['sizes']['blog-large']; ?> 1000w" sizes="…" src="<?php echo $img['sizes']['blog-small']; ?>" alt="…">
And there you have it. Upload one image in ACF, get a responsive image on the frontend.
I don’t make a habit of writing PHP so if you can improve on this please do so in the comments or get in touch on twitter or email, links at the bottom.