1

I'm trying to make a Wordpress theme and I'm very confused about how I should use responsive images. Here's how I'm currently displaying each thumbnail in my post list:

<? the_post_thumbnail() ?>

The output is:

<img
    width="2560"
    height="1710"
    src="https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1.jpg"
    class="attachment-post-thumbnail size-post-thumbnail wp-post-image"
    alt=""
    decoding="async"
    loading="lazy"
    srcset="
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1.jpg 2560w,
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1-300x200.jpg 300w,
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1-1024x684.jpg 1024w,
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1-768x513.jpg 768w,
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1-1536x1026.jpg 1536w,
        https://wordpress.local/wp-content/uploads/2022/11/photo-scaled-1-2048x1368.jpg 2048w
    "
    sizes="(max-width: 2560px) 100vw, 2560px"
/>

And it renders like this:

Screenshot

Each thumbnail is (currently) 430x275 px, so I would expect the 768x513 version of the image to be displayed. However, when I hover the image, Chrome says the "current version" is the "1536x1026" version:

Screenshot

This is unnecessarily large, and Lighthouse yells at me for showing improperly scaled images:

Screenshot

So how do I fix this? I just want to render the image and have the browser pick the most appropriate source for the current image size.

I assume this is because the sizes attribute is set to 100vw, which causes the browser to always show an image that is larger than the current viewport width (or 2560px). Can I customize this?

If I choose to render a specific size, for example: <? the_post_thumbnail("thumbnail") ?>, then Wordpress doesn't render the srcset or sizes attribute at all, completely breaking responsiveness.

I feel like I'm missing something obvious. How am I supposed to:

  • Render a post thumbnail, having the browser pick the smallest possible source that fits the image size
  • Also render srcset so the browser can choose a higher resolution image on high-resolution displays

1 Answer 1

2

Render a post thumbnail, having the browser pick the smallest possible source that fits the image size

You need to provide a sizes attribute that describes what size the image will be rendered at across various breakpoints.

The final display size of an image is affected by the stylesheet but the browser wants to start loading the image before the stylesheet has been loaded. This means that it doesn't actually know which size from the srcset to use. Therefore you need to provide this information using the sizes attribute.

When using the_post_thumbnail() you can set the sizes attribute like so:

the_post_thumbnail(
    'post-thumbnail',
    array(
        'sizes' => '(max-width: 960px) 50vw, 430px', // Just an example.
    ),
);

For images that are inserted into the editor, the srcset and sizes attributes are applied to images using the the_content filter when the content is rendered. To set a more appropriate sizes you need to use the wp_calculate_image_sizes filter.

add_filter(
    'wp_calculate_image_sizes',
    function( $sizes ) {
        $sizes = '(max-width: 960px) 50vw, 430px'; // Also just an example.

        return $sizes;
    }
);

It's not possible for me to tell you exactly what value you want for sizes, since it depends on what your site looks like across screen sizes, which I don't know. It's also not specific to WordPress, so it's not really on topic here. The MDN article on responsive images is a good overview of how these attributes are supposed to be used.

Also render srcset so the browser can choose a higher resolution image on high-resolution displays

As I mentioned above, WordPress will automatically add the srcset attribute to images in post content. It will also add it to the_post_thumbnail() (or wp_get_attachment_image()) if you don't specify it yourself.

When you upload an image WordPress will automatically create 'thumbnail', 'medium', 'medium-large', 'large' and 2560px-wide versions of the image. Images will also be created for any custom sizes created with add_image_size() or set_post_thumbnail_size(). WordPress uses these versions to populate the srcset attribute.

The important thing to note is that images in the srcset attribute need to be the same aspect ratio (use the <picture> element for having different image dimensions at different sizes). This means that any hard-cropped sizes like the square thumbnails will not have any alternative sizes for the srcset attribute unless the original source image happened to be the same aspect ratio, or additional custom sizes were registered with the same aspect ratio.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.