Following the news that WordPress 4.4 shipped yesterday, I thought I’d take some time to detail one of its most exciting new features: built-in support for responsive images.
If you’re wondering what that means, have no fear. By now, you probably understand what a responsive website is, and why it’s important to have one in today’s web. Responsive websites are designed to look nice on a wide variety of screen sizes by optimizing the display of the content for any given screen width. In other words, instead of having a separate “mobile” version of your site, the same website can be be accessed on desktops, laptops, tablets, and phones (and maybe even smartwatches!), with a user experience that is catered to the screen size of the device they’re on.
Responsive images are a part of this. Just like the rest of the site, images should be optimized for whatever screen they’re being viewed on. This means delivering crisp images for screens with a high pixel density (e.g. “retina” screens), but also avoiding the use of unnecessarily large, bulky images.
For instance, a 300 pixel wide logo may look great on my desktop PC, but on my retina iPad or iPhone, the same image would appear blurry. The solution is to use a 2x resolution image (twice as large, or twice as dense, depending on how you want to think about it) on high-density displays, but not on regular old 1x density screens. Similarly, I may want to use a 960 pixel wide image on a desktop site, but this is overkill for someone on a 320 pixel wide phone screen; I don’t want to eat up all of my visitors’ cellular data plan, after all.
Where things become tricky
Unfortunately, dealing with responsive images can sometimes get messy. The best way to swap out resolutions in images is, in most cases, to just use the srcset attribute on image tags, which is supported in most major, modern browsers (with the notable exception of Internet Explorer, even up to version 11). But this can really slow down your coding, if you suddenly need to to include all of this extra information about alternate image sources in your markup. It’s fine when you’re only writing theme templates and perhaps have a dozen or two images to include. But what about when you’re building the internal page content on your site? Are you— or even worse, a client— really supposed to manually add in the srcset attribute for every single image you use in a page or post?
Let’s be honest. Nobody has that kind of time, and unfortunately, the process of manually adding an srcset to every image on every page you create is far too prone to error. There have been, however, some interesting attempts to solve this problem. A script called retina.js, for example, automatically checks your server for 2x versions of every image on a page (assuming that they follow the proper naming convention) and substitutes in the 2x image whenever it’s needed and available. Still, this doesn’t help when you’re more worried about screen width than pixel density, and its biggest downside is that it still requires that all of the 1x versions of the images be downloaded first, which leads to more bloat and cellular data usage. To me, that’s a dealbreaker.
So, what’s a developer to do?
Thank you, WordPress
Until now, I’ve been patiently using the srcset attribute in my theme templates, along with CSS media queries to handle my responsive background images (I use a SCSS mixin that makes it easy to use 2x background images on high-density displays). I don’t expect any of that to change, as it’s all been working out quite well.
What will change is how I handle pages and posts on my WordPress sites— those situations where manually adding the srcset attribute under the text editor tab isn’t really a viable option. And the most beautiful thing is that I don’t really have to do anything!
Before WordPress 4.4 was released, the only way to achieve responsive images within posts was to use a plugin like RICG Responsive Images. Now, however, much of that functionality comes baked right into core.
You’re probably used to WordPress automatically generating different versions— each a different size— of every image you upload (i.e. “thumbnail,” “medium,” and “large”). From now on, one additional image size (“medium-large,” which has a width of 768 pixels) will be secretly generated behind-the-scenes. This will enable your browser to serve up an image more optimized for the size of the screen on which it’s being viewed.
The new feature uses a combination of the srcset and sizes attributes, which are explained in a little more detail here. Essentially, these instructions tell your browser which image it should use under which circumstances. From a back-end user perspective, nothing will really change; most authors will never have any idea that anything is different. In fact, even the HTML markup that gets generated when you insert an image into a post appears the same— at least in the text editor.
The magic happens when WordPress filters the output on the front end of your site; suddenly, what appeared in my editor as this:
<img class="alignnone size-medium wp-image-72" src="http://testsite.dev/wp-content/uploads/2015/12/test-300x154.png" alt="Test Image" width="300" height="154" />
Now appears in my page source as this:
<img class="alignnone size-medium wp-image-72" src="http://testsite.dev/wp-content/uploads/2015/12/test-300x154.png" sizes="(max-width: 300px) 100vw, 300px" srcset="http://testsite.dev/wp-content/uploads/2015/12/test-300x154.png 300w, http://testsite.dev/wp-content/uploads/2015/12/test-768x395.png 768w, http://testsite.dev/wp-content/uploads/2015/12/test-1024x527.png 1024w" alt="Test Image" width="300" height="154" />
And, remarkably, my browser displays the correct version of the image!
Of course, if you feel the need to tweak the default srcset or sizes attributes, you can always do that via a filter. At the time of writing, neither of these filters are yet listed in the Plugin API/Filter Reference, but they’re called wp_calculate_image_srcset and wp_calculate_image_sizes, respectively. If you want to tie the new srcset feature into your plugin or theme (e.g. for featured images or post thumbnails which are not rendered as part of the post content), the function you’re looking for is wp_get_attachment_image_srcset(), which is also, at the time of writing, absent from the WordPress Codex.
It’s also worth noting that this will only work in browsers that support it; if you really need srcset and sizes to work in IE, you may consider using a responsive images polyfill. Then again, the nice thing about srcset and sizes is that they degrade gracefully; browsers without support will just display the regular old image specified by the src attribute as a fallback (for this reason, I don’t bother with polyfills, as they add extra overhead that, in my mind, isn’t justified in a case like this).
Anyway, if you’re interested in further reading, you can check out this post on the WordPress core development blog. Otherwise, go ahead and try it out ( just make sure you’ve updated your site to WordPress 4.4 first, and then add media as you normally would)! Happy updating!