So you are using WordPress right? Or maybe another modern CMS which supports responsive image srcsets? Alright, so you are a true pioneer rocking your own framework? Regardless of how your images get those helpful “srcset” attributes, this article will apply to you.
Real quick refresher… the srcset
attribute allows your browser to select the appropriate image src
based on the current screen size and pixel density. This way you can load retina images or smaller versions depending on how you are viewing the site so everyone gets the best experience.
Following me so far? If not, there is a ton of useful information online about image srcsets.
Let’s get into why we are really here, the sizes
attribute. This one is a lot less known and understood but just as or more important than srcset
.
Let’s say you have an image with a few optional `src` which are all defined properly via your srcset
. If your image is displayed the full width of the screen, your good to go. The browser will automatically fill in the correct image and there is nothing left to worry about.
But what if your image is not the full screen width, or what if the image width changes responsively depending on how wide the screen is? The browser is going to assume the image is the full screen width and will never switch to a smaller version when the image is not full screen width. This probably still looks fine, but your loading larger images than you need to and your srcsets
are potentially pointless.
Let’s try a real world example.
You have a gallery of images or posts which display in 3 columns when on a desktop then move down to 2 columns on tablet and full width on a phone. Let’s imagine we are using the following breakpoints via CSS to handle the columns
- max-width: 750px – width: 95% (full width columns for phones)
- max-width: 1200px – width: 46% (2 columns for tablets)
- anything over 1200px – width: 30% (3 columns for desktops)
Which gives us CSS which will look something like this:
Now you have your image generated which looks something like this with 2 available sizes.
When the browser is deciding which src
to use from the srcset
it does not take your CSS into consideration and does not know that images may only be 30% of the screen wide. It will always treat the image as being the full width of the screen.
This is where the
sizes
attribute comes in.
We get to tell the browser the display size of the image based on the screen width using semi-familiar media queries.
While technically we can use exact px
declarations, we are using a responsive CSS layout which uses percentage so it works best to follow the same pattern on the images. There is no %
available within the sizes
attribute but we have the same thing called vm
. When you see vm
think “percentage”.
The rules of the sizes attributes:
- You may add as many media-queries as you would like to the tag.
- Each rule will be checked, starting at the left, until one matches.
- Only the first matching rule is applied.
Our rules in order:
- If the screen is smaller than
750px
, the image will be95%
the width of the screen. - If the screen is smaller than
1200px
the image will be46%
the width of the screen. - If the screen is larger than
1200px
the image will be30%
the width of the screen.
Important Note:
We put the smaller width options first because only the first matching rule is used and since we are using max-width
it is important that the smallest match be applied.
We end up with an image which looks like this:
Implementing this in WordPress
When WordPress added support for srcset
and sizes
back in version 4.4 it came with a filter for adding custom image sizes called wp_calculate_image_sizes
.
This may be added as is to a particular template to target just one area. There is also the $sizes
and $size
parameters in case you want to add this somewhere global like functions.php
and need to build in conditionals for targeting different image sizes or areas of your site.