WordPress Responsive Images Explained
In this tutorial, I want to dive deep into the functionality of WordPress responsive images, which appeared in the 4.4 version of the core. If you ever wondered how this functionality works, then this tutorial is probably what you need.
How to Disable Responsive Images in WordPress
In the post content
Let’s assume that you insert a nice and clean image into your post content, something like this:
<img src="image.jpg" class="wp-image-12345" alt="misha test image" />But inside your actual content on the website it becomes something like:
<img src="image.jpg"
class="wp-image-12345"
alt="misha test image"
srcset="image-300x150.jpg 300w,
image-400x200.jpg 400w,
image-500x250.jpg 500w,
image-1024x512.jpg 1024w"
sizes="(max-width: 1024px) 100vw, 1024px"
/>How can we prevent that from happening? (if you don’t need that, of course).
First of all, you can simply remove the wp-image-{$image_id} class from an image’s HTML:
<img src="image.jpg" alt="misha test image" />Or use the following filter hook:
remove_filter( 'the_content', 'wp_make_content_images_responsive' );That’s it.
Everywhere else
If removing srcset and sizes attributes from the post content is not enough, and it could be not enough, because WordPress hooks them in other places as well, for example, when you call the_post_thumbnail() function to display featured images.
In that case, you could simply tap into the wp_calculate_image_srcset() and wp_calculate_image_sizes() functions. Specifically, we need the hooks inside them: wp_calculate_image_srcset_meta and wp_calculate_image_sizes.
add_filter( 'wp_calculate_image_sizes', '__return_empty_array', 9999 );
add_filter( 'wp_calculate_image_srcset_meta', '__return_empty_array', 9999 );WordPress Functions to Work with Responsive Images
In this chapter, you will find some documentation for the main WordPress functions to work with responsive images:
wp_get_attachment_image_srcset,wp_get_attachment_image_sizes,wp_image_add_srcset_and_sizes.
Let’s jump into it.
wp_get_attachment_image_srcset
This function returns a value for a given image’s srcset attribute.
The srcset attribute contains a list of URLs of an image (using its generated image sizes), and allows a browser to choose the most appropriate image (an image size in our case) depending on a provided screen size, resolution, or viewport.
The simplest example:
<img src="image.jpg" srcset="image.jpg 1x, image@2x.jpg" />In simpler words, it means, if we watch the page via an old monitor, image.jpg will be displayed; if we watch it on a retina display, then image@2x.jpg will be displayed.
Well, that’s an interesting theory, but how does the wp_get_attachment_image_srcset() function generate all of this?
Ok, the wp_get_attachment_image_srcset() function loops through all registered image sizes on your WordPress site and adds each size into the value for the scrset attribute in the following format: image-{WIDTH}x{HEIGHT}.jpg {WIDTH}w.
Please note that the function ignores the following image sizes:
- if the resized image ratio differs from the original more than 0.002,
- if the resized image was edited,
- animated GIF images,
- if the resized image width is more than maximum scrset image width (by default 1600 but can be hooked with
max_srcset_image_width).
How about a custom example?
$attachment_id = 1234;
printf(
'<img src="%s" srcset="%s" />',
wp_get_attachment_image_url( $attachment_id, 'thumbnail' ),
wp_get_attachment_image_srcset( $attachment_id, 'full' )
);
/*
<img
src="DOMAIN/wp-content/uploads/2026/07/image-100x100.jpg"
srcset="DOMAIN/wp-content/uploads/2026/07/image-120x90.jpg 120w, DOMAIN/wp-content/uploads/2026/07/image.jpg 975w" />
*/wp_get_attachment_image_sizes
This function generates and returns the value of a specific image’s sizes attribute.
In simple words, the sizes attribute is only needed for non-fullwidth images; for example, if you need an image to be only 50% of the viewport/screen width for a specific device, let’s say.
For example, if we take a look at this rule: sizes="(max-width: 400px) 100vw, 50vw", how can we read it? Simple – just read it from left to right!
- IF the screen (viewport) width is 400px or less, then the image should take up
100vw(100% of the screen width). - ELSE the image will take up
50vw(half of the screen width).
There could be plenty of conditions here.
What about the wp_get_attachment_image_sizes() function, by the way? To be honest, it is simply a wrapper function, and it doesn’t do a lot – it simply relies on the wp_calculate_image_sizes() function to return the value of the sizes attribute, and, unless it is hooked with the wp_calculate_image_sizes hook, the default value will always be the same: (max-width: {WIDTH}px) 100vw, {WIDTH}px, where {WIDTH} is the actual width of the file.
$attachment_id = 1234;
printf(
'<img src="%s" srcset="%s" />',
wp_get_attachment_image_url( $attachment_id, 'thumbnail' ),
wp_get_attachment_image_sizes( $attachment_id, 'full' )
);
/*
<img
src="DOMAIN/wp-content/uploads/2026/07/image-100x100.jpg"
sizes="(max-width: 975px) 100vw, 975px" />
*/This function is a wrapper for the wp_calculate_image_srcset() function.
wp_image_add_srcset_and_sizes
The function itself is pretty straightforward: when you pass an <img> tag into it with both provided variables – $image_meta and $attachment_id, it will return an HTML of the image with both srcset and sizes attributes added. It works based on the two functions we have already discussed in this lesson – wp_calculate_image_srcset() and wp_calculate_image_sizes(). In other words, it just works with regular expressions.
$image_html = sprintf(
'<img src="%s" />',
wp_get_attachment_image_url( $attachment_id, 'thumbnail' )
);
$image_meta = wp_get_attachment_metadata( $attachment_id );
echo wp_image_add_srcset_and_sizes( $image_html, $image_meta, $attachment_id );
/*
<img
src="DOMAIN/wp-content/uploads/2026/07/image-100x100.jpg"
srcset="DOMAIN/wp-content/uploads/2026/07/image-120x90.jpg 120w, DOMAIN/wp-content/uploads/2026/07/image.jpg 975w"
sizes="(max-width: 975px) 100vw, 975px" />
*/What is not straightforward is – how to use srcset and sizes attributes together?
<img src="image.jpg"
srcset="image-400x200.jpg 400w, image-1000x500.jpg 1000w"
sizes="(max-width: 768px) 100vw, 50vw">Let’s imagine two scenarios:
- When a user visits a website from a smaller screen (let’s say
375pxwide), the browser first checks conditions inside the sizes attribute and sees that we need to use an image for the 100% width of the viewport, which is, as I mentioned before –375px. Then the browser checks the srcset attribute and gets an appropriate image for the given width – for375pxwidth, it will be the first condition,image-400x200.jpg. - Now, let’s take a look at a scenario when a user visits a website from a bigger screen; we can take a look at two sub-scenarios here –
800pxand1000px.800px– at first, from thesizesattribute, the browser understands that we need to use an image for 50% of the viewport,800 / 100 * 50% = 400, but then we go to thesrcsetattribute and see that in this case, the browser will loadimage-400x200.jpg.1000px– the image of 50% of the viewport here will be500px, and from thesrcsetattribute we can understand that the image will beimage-1000x500.jpg.
It is very interesting to understand, and I really hope that I explained it well.
How to Use Images with Different Ratio?
Look at the picture below. Which image do you think looks better on the device screen?

You may notice that the image ratio (width/height) differs, so WordPress wouldn’t add the needed image size to the scrset attribute. How to force it to do it:
add_filter( 'wp_calculate_image_srcset', 'rudr_custom_sources' , 25, 5 );
function rudr_custom_sources( $sources, $size_array, $image_src, $image_meta, $attachment_id ){
/*
* Your variables here
*/
$image_size_name = 'square500'; // add_image_size( 'square500', 500, 500, true );
$breakpoint = 500;
$upload_dir = wp_upload_dir();
$img_url = $upload_dir[ 'baseurl' ] . '/' . str_replace( basename( $image_meta[ 'file' ] ), $image_meta[ 'sizes' ][ $image_size_name ][ 'file' ], $image_meta[ 'file' ] );
$sources[ $breakpoint ] = array(
'url' => $img_url,
'descriptor' => 'w',
'value' => $breakpoint,
);
return $sources;
}For a better user experience, you can use the Manual Image Crop plugin to crop the image the way you want.

Plugins Compatibility
When it comes to third-party plugins, I had a chance to work with some of them that do not fully support this responsive image feature in WordPress. As a result, WordPress displays srcset and sizes, but inside these attributes we simply have links to broken images. The funny thing is that you may not even notice it on your desktop, but your users, let’s say, on an iPad (or something), will see broken images.
So, my recommendation here is to not forget to test third-party plugins on different mobile devices as well.
But what about my plugins?
Sure thing, I did my best, so all of my plugins fully support the entire WordPress default functionality (which includes responsive images).
The only thing to keep in mind is that if you’re working with a plugin which involves using multiple WordPress sites – please do not forget to register the same image sizes on all sites used by the plugin.
| Plugin name | Compatibility |
|---|---|
| Simple Multisite Crossposting | Yes – but I recommend registering the same image sizes on all sub-sites used for crossposting. |
| Simple WP Crossposting | Yes – but I recommend registering the same image sizes on all sites used for crossposting, especially if you use the “Copy Attachments” option. |
| Multisite Shared Media Library | Yes – the plugin takes every image size from the main media library, for both srcset and sizes attributes. |
| Simple Media Library Folders | Yes – basically, it simply organizes your media, and responsive image sizes aren’t affected in any way. |
If you have any questions, welcome to the comments section.
Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Is it possible to adapt the “misha_sources” function to accept multiple custom image sizes? Been trying for a couple of days now, but I can’t seem to get it to work.
Thank you for your code, Chris,
At first look, I noticed two mistakes:
1. You’re using
return $sourcesinside the foreach loop. In other words, the loop always has only one iteration.2. For multiple custom image sizes, you will need multiple values of the
$breakpointvariable as well.Start with fixing this things.
Hi
Thank you so much for your helpful blog article. How do I set scrset and sizes attributes in the functions.php for all images? Im using the default wp-image-block and I cannot set these direct in the HTML. Thank you so much.
Hello,
I would like to have 2 versions of each image, one for large screen and one for mobiles. (I use Enfold theme).
If I already have a 1000×664 px image in my media library, which is too heavy for mobile, Do I need to upload a second size of my original image (for example 500×330 px) ? If yes, where do I upload It ?
Thanks in advance and thanks for sharing !
Christopher
Hello Christopher,
You don’t need to create a second copy of an image and upload it again, instead, you need to register one more image size.
Hi Misha, great article (again)!
I have a question about background images, i’m using a ‘partial block’ with a background image on multiple pages, now this block will change in width if you got a bigger or smaller screen. My question is; Is it possible to use functions like
wp_get_attachment_image_sizes()for background images, and show the right one on the right width?Thanks!
Hi René, thank you! And sorry for the late reply!
If you’re using CSS inside the PHP code, in theory, you can tap into the
wp_calculate_image_srcset()function (it will return an array, and then you can use the data from the array to generate CSS).