How to use the responsive images feature from WP 4.4 in your themes

I don’t really understand how I can use the new responsive images feature that WordPress provides in my themes.

Example:

In my theme, I add a header-image. I therefore use the custom-header-image from customizer OR the post-thumbnail:

<figure id="header-image" class="uk-margin-remove">
<?php if ( ( is_single() || ! is_home() ) && has_post_thumbnail() ) : ?>
    <?php the_post_thumbnail(); ?>
<?php else: ?>
    ???
<?php endif; ?>
</figure>

So in the first case, the output is this:

<img src="http://xxx.dev/wp-content/uploads/x.jpg" srcset="http://xxx.dev/wp-content/uploads/x-300x70.jpg 300w, http://xxx.dev/wp-content/uploads/x-768x180.jpg 768w, http://xxx.dev/wp-content/uploads/x-1024x241.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" alt="">

which is perfectly fine. But If I want to display an image by attachment ID, no matter which function I use, I don’t get the output I expect.

Example:

In the code above you see “???”. In that place, I tried some things. For example this:

<?php echo wp_get_attachment_image( get_custom_header()->attachment_id, 'full' ); ?>

Which only results in one size (see sizes attribute):

<img src="http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922.jpg" class="attachment-full size-full" alt="Delft_IMG_6275" srcset="http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922.jpg 1920w, http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-300x70.jpg 300w, http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-768x180.jpg 768w, http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-1024x241.jpg 1024w" sizes="(max-width: 1920px) 100vw, 1920px" height="451" width="1920">

So, what’s the proper way of displaying images in the theme so that it outputs a similar result as the_post_thumbnail()?

Solutions Collecting From Web of "How to use the responsive images feature from WP 4.4 in your themes"

Following our exchange in the comments I’ve reread your question and have a pretty straightforward answer:

It looks like it’s working fine.

You are worried about the sizes attribute in your second example, but it’s the srcset attribute that you should look at and it is showing all of your image sizes:

<img 

src="http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922.jpg" 

class="attachment-full size-full" alt="Delft_IMG_6275" 

srcset="http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922.jpg 1920w,
http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-300x70.jpg 300w,
http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-768x180.jpg 768w,
http://xxx.dev/wp-content/uploads/Delft_IMG_6275-e1453192498922-1024x241.jpg 1024w"

sizes="(max-width: 1920px) 100vw, 1920px"

height="451" width="1920">

Your browser reads the attributes like this:

1 – Look at the sizes attribute and find the first match for the current viewport width. In this case, if the viewport is anything up to 1920px wide, then use the 100vw value, converted to px, otherwise use 1920px.

2 – Look at the srcset attribute and choose an image that fits the value from (1).

On a nice big screen with a full width window the browser chooses the sizes value of 1920px. This points the browser to the image marked with 1920w in the srcset attribute, with the URL of your full size image.

On a portrait iPad, where the viewport is 768px wide, the value obtained in (1) will be 100vw which for this viewport is 768px. Looking in the srcset for 768w we get the URL to the medium_large image size (a new default size in WP4.4 which doesn’t show in the admin interface).

When there’s no exact match for the viewport width, the browser should choose the next size up.

Now, there are circumstances where you might want to supply a longer list of images which you can add using add_image_size() in your theme. WP will build a srcset attribute using all the images that match the aspect ratio of the image size you choose to display.

There are also circumstances where you want a custom sizes attribute and you can filter the attribute for that, but as your question stands I don’t think that’s what you’re after.

On the one hand, there is nothing you should do, on the other, wordpress do not actually create responsive images.

WordPress will create a srcset attributes whenever you use the image related APIs based on the registered image sizes, with all the images that match the aspect ratio. What you need to do is to have the relevant image sizes registered in order for wordpress to be able to generate the images, and use them in a srcset.

In your “failed” example full images will never be responsive since wordpress will not generate images that are bigger then the original image (and in any case it is tricky to code an image generation for size that change from one image to another).

What you need to do in your theme is to decided which sizes you want to support and define them first. for example if you want a 150×150 thumbnail to be served also to x2 retina then you will need to register both a 150×150 size and 300×300 size. If on mobile you allocate a 50×50 space for the thumbnail, then you will also need to register also a 50×50 and 100×100 (for retina) sizes, not sure this is wise in practice but that is the theory of it.

Rant: Calling what wordpress core does a feature is an insult to intelligence. It is a sweetener to help you avoid doing many API call, but it does not help you with actually designing what size you actually need, and still keep it tedious to configure wordpress to use them.

You could use an array as size:

wp_get_attachment_image( get_custom_header()->attachment_id, array('700', '600'));

EDIT:

@downvoter say why you are downvoting. I agree I was in a way wrong, but you could have said “Yes you can use an array to size the image, BUT, it will only default to the nearest size to a defined image size.

Defined images are either set in the media section of SETTINGS->MEDIA in the backend admin, these will be “thumbnail, “medium’ and “full” OR by custom use and you can use add_image_size('name-you want-use', 340, 230, true); in your functions file ETC…ETC..