Here's a good CSS Tricks article on Responsive Images. The upshot is that srcset gives the browser different sizes of the same image to choose from. Sizes lets you tell the browser how wide you expect the image to be at various screen widths. If you don't declare sizes, the browser will just assume that the image will be displayed at 100vw at all screen sizes. So if you know that at 768px and up, this image will only occupy half the screen width, declaring that in your sizes attribute can save wide-screen devices from downloading too-large image sources.
You can generate a very basic image tag by hand using something like:
<?php
if( get_field('image_field_name') ) { ?>
<img src="<?php echo get_field('image_field_name')[url]; ?>" alt="<?php echo get_field('image_field_name')[alt]; ?>">
<?php } ?>
BUT that completely misses the awesome automatic srcset generation that WP will do for you! There are a couple of cool functions built in to WP that set up an img tag with a srcset so browsers get the proper size image responsively!!! (In addition to setting the alt text and a bunch of other stuff too :)
They are wp_get_attachment_image()
and get_the_post_thumbnail()
(Note: I need to explore the exciting wp_prepare_attachment_for_js($attachment_id)
function -- it gives access to all the things.)
They accept almost the same arguments:
get_the_post_thumbnail( int|WP_Post $post = null, string|array $size = 'post-thumbnail', string|array $attr = '' )
wp_get_attachment_image( int $attachment_id, string|array $size = 'thumbnail', bool $icon = false, string|array $attr = '' )
Note that wp_get_attachment_image()
takes an extra $icon argument. I've never used it, but don't forget to pass false
or ''
or null
as your third argument or it'll assume your attributes are the $icon and try to apply them :P
Also note that get_the_post_thumbnail()
takes the post id as its first argument, and returns the featured image of that post. If your image is stored in another field (such as an ACF field), you'll want to use wp_get_attachment()
instead. It takes the attachment_id (<-- different from the post_id!) and returns the image stored in that field.
Here's an example of a basic srcset of an ACF image field that's set to return an image ID:
<?php
if( get_field('image_field_name') ) {
echo wp_get_attachment_image( get_field('image_field_name'), 'wp_image_size' );
} ?>
And here's an example of a basic srcset of an ACF image field that's set to return an image array:
<?php
if( get_field('image_field_name') ) {
echo wp_get_attachment_image( get_field('image_field_name')['id'], 'wp_image_size' );
} ?>
This will return an image tag with a srcset that includes all the all the wp image sizes that exist for that photo that have the same proportions as the wp image size that you selected. Since Rootid is using a function that automatically generates x2 (and sometimes x3) versions of each image size, unless the client uploads a ridiculously small original (WP won't crop images that are smaller than either dimension of your image size definition), we're going to have a few srcsets to play with :)
Both wp_get_attachment_image()
and get_the_post_thumbnail()
can optionally accept $attr, which allows you to pass sizes to your image. (You can pass all sorts of attributes, like classes too. Just add another element to your attributes array, such as 'class' => 'my_awesome_class_name' )
For the INM site, we had a listing page with listing items 4 across on screens > 992px, 3 across on screens > 768px, 2 across on screens > 576px, and full-width on smaller screens. So small tablets needed a higher resolution image than big-screen devices! Using the sizes attribute, I could let the browser know how large the image was going to be to save downloading a larger image than necessary.
Here's an example using wp_get_attachment_image()
:
$listing_item->image = wp_get_attachment_image( get_post_thumbnail_id($listing_item->id), 'squarish', false, [ "sizes" => "(min-width: 992px) 25vw, (min-width: 768px) 33vw, (min-width: 576px) 50vw, 100vw"]);
Upon reflection, since the image that I was accessing is the featured image, it would have been easier to use get_the_post_thumbnail()
like so:
$listing_item->image = get_the_post_thumbnail( $listing_item->id, 'squarish', [ "sizes" => "(min-width: 992px) 25vw, (min-width: 768px) 33vw, (min-width: 576px) 50vw, 100vw"]);
Either way, the html that is produced is identical. Here's an example of one image generated with this code:
<img width="200" height="161" src="http://institute-for-natural-medicine.test/wp-content/uploads/2018/10/EleanorWarshaw-200x161.jpg" class="attachment-squarish size-squarish wp-post-image" alt="" sizes="(min-width: 992px) 25vw, (min-width: 768px) 33vw, (min-width: 576px) 50vw, 100vw" srcset="http://institute-for-natural-medicine.test/wp-content/uploads/2018/10/EleanorWarshaw-200x161.jpg 200w, http://institute-for-natural-medicine.test/wp-content/uploads/2018/10/EleanorWarshaw-400x322.jpg 400w, http://institute-for-natural-medicine.test/wp-content/uploads/2018/10/EleanorWarshaw-600x483.jpg 600w" title="">
Using WordPress Responsive Images with Advanced Custom Fields