With the release of WordPress 4.4 in December, WP core now comes packaged with responsive image support. Although the WP team announced “you don’t need to do anything to your theme, it just works,” there are a few things theme developers will want to modify to get the most out of this new feature.
Srcset & Sizes
The new responsive image feature in WP 4.4 relies on adding
sizes attributes to all content and thumbnail images.
Srcset is exactly what it sounds like, a set of sources where the browser can find the desired image at different sizes. In addition to the URL for the image, the image’s width is also included in the
srcset. An example
srcset might look something like this:
srcset= “img-300x200.png 300w, img-600x400.png 600w, img-1200x800.png 1200w”
srcset specified, your browser can do some quick math to determine which of these images is going to work best based on viewport width and device pixel density. It will then serve up only that image. For example, if someone hits your site from a 320px wide iPhone, their browser won’t have to download a 2400px image. Not only will your site be faster, but users on a limited data plan just might thank you.
If you’d like a quick overview of how the browser chooses which image to serve, checkout this css tricks article.
Now that we’ve covered
srcset, you might be wondering why the
sizes attribute is necessary. Well firstly,
sizes is now a mandatory requirement according to the specification. Additionally,
srcset by itself doesn’t account for any CSS being applied to the image. The
sizes attribute is essentially a set of media queries that tell the browser the width of an image at various breakpoints. An example
sizes attribute might look something like this:
sizes= “(max-width: 768px) 92vw, (max-width: 992px) 690px, 910px”
The markup for this meaning:
sizes = “(media query) width, (media query) width, fallback width”
And an English translation:
“When my viewport is less than 768px wide, my image takes up 92% of the screen. When my viewport is greater than 768px but less than 992px wide, my image is 690px wide. Otherwise, my image is 910px wide.”
Width can be either fixed or relative: ems, pixels, and vws are all supported. Depending on your design, you might find yourself using a mixture.
By default, WordPress injects the following default sizes attribute:
sizes= “(max-width: [image width]) 100vw, [image width]”
This default setting stops the browser from providing an image source that is larger than the size requested. However, if your image is modified by CSS in any way, this default setting is not optimal. In order to address this issue, WordPress has added some hooks to help you customize the output of the
sizes attribute on content and thumbnail images. Let’s dig a little deeper and see how we set this up on our open source starter theme, Silencio, but first…
Before we get into how to set this up on your theme, a quick note on browser support.
Srcset has solid support almost everywhere except Internet Explorer. Now, your images won’t be broken in IE if you update to 4.4,
srcset falls back gracefully on the
src attribute. However, if you want to get the benefit of responsive images across browsers, you’ll have to add a polyfill for IE support. We chose picturefill, which was originally included in the RICG Responsive Images Plugin that eventually became part of WP Core.
Customizing Responsive Images For Your Theme
For this example, we’ll be using VIA Studio’s open source, content-first starter theme Silencio as an example. If you haven’t checked it out, please do!
There are two hooks you should use in your theme’s functions.php file to optimize the
sizes attribute. They are wp_calculate_image_sizes and wp_get_attachment_image_attributes.
Let’s start with wp_calculate_image_sizes, which will allow us to customize the
sizes attribute on content pages.
Start by defining your function and hooking it into wp_calculate_image_sizes:
Then, identify the different layouts your theme uses that could affect the size of content images. In the case of Silencio, our default page and post template is a two column layout, with a main column and a smaller sidebar. We also include a template for full width pages, which do not include the sidebar. Since pages and posts are the same, we only need to check for the full width template, so we’ll add that check inside our function. We’ll also need to know the width of our image, so we’ll add a $width variable.
Next, you’ll need to identify your theme’s breakpoints and how images work within each breakpoint. Silencio’s layout is based on Bootstrap and uses their breakpoints, so we will have to identify how content images work within those breakpoints. Since Silencio’s column widths are fixed except on mobile, we’ll be working primarily with fixed pixel sizes instead of relative sizes.
At our largest breakpoint, 1200px wide, large content images can only span 910px wide in the full width template and they can only span 597px wide in all other templates. On screens any larger, they will never be over 1100px or 730px wide, respectively. At the smallest breakpoint, 768px wide, they span 690px or 450px. On screens any smaller, both will take up 92% of the screen’s width. Let’s add this to our function.
*Note: content images in Silencio have
max-width: 100%; applied in the theme’s CSS to prevent them from breaking outside of their bounding boxes.
Do the same calculations for images of smaller sizes, and then add a fallback for smaller images. Your final function might look something like this:
Now we’ll want to do something similar for your site’s thumbnails. First, identify the custom thumbnail sizes for your site. In Silencio we have a ‘header-thumb’ and a ‘blog-thumb.’ Now, look at how these different sizes work at your breakpoints and hook into wp_get_attachment_image_attributes. Your final function might look something like this:
That’s all there is to it! These functions will vary based on your theme’s design and CSS, but hopefully you now have a basic understanding WordPress 4.4’s new responsive images feature. Happy blogging!
Want some more info on responsive images? Here are a few resources I’d recommend: