Responsive images make websites look better by displaying sharper images on large and small screens. And they make websites load faster by sending the ideal image size to every device type. That’s good for viewers, clients and Search Engine Optimization, as Google uses page load speed as a ranking factor. And what’s good for clients, viewers and Google is good for web design agencies. You can should use responsive images for all websites, and for WordPress websites, it’s especially easy as responsive images are built in to the WordPress content management system automatically. This is one of our favorite web design tricks to make faster loading, better looking and higher performance websites

diagram from US patent 1,867,377 depicting otto rohwedder's 1928 patent for the bread slicing machine

A bit of history – sliced bread was invented in 1928 by Otto Frederick Rohwedder of Davenport, Iowa. He was so convinced that he could make a machine to slice a loaf of bread all at once that he sold his jewelry business to fund the cause. He made an early prototype of a bread slicing machine, but it was destroyed in a fire. It took him 16 years to get the the machine finished. The first actual slice of sliced bread was sold on July 7th 1928. Think that was a long time ago?

Responsive images were introduced into the WordPress core waaaaaaaaaaay back in 2015 – December 8 to be exact – in the release of WordPress version 4.4, named for jazz musician Clifford Brown. Since it’s a well known fact that internet time is exactly 20.26x regular time, responsive images were invented just days after sliced bread, which makes them clearly the greatest thing since.

Take a look at the Merge Proposal that pushed responsive images into the WordPress core to find out why this technology was included in WordPress:

8:57 am, September 30, 2015

As of today, the average web page currently weighs over 2 MB with the majority of those bytes being attributed to images. Screen density and display sizes continue to increase and site owners are including larger image assets to keep up, causing slower page load times for people on smaller/older devices and on slower/expensive network connections. We have the opportunity to make a huge impact on the ~25% of the web that runs on WordPress by adding responsive image support out of the box so sites can serve appropriate sizes images to all users.

Those reasons have only become more pressing. So what are responsive images, how do they work and how can we use them to be better web developers to make faster websites that rank higher on search engines? Let’s get into it.

example of responsive images shown in WordPress shown on three different screen sizes - mobile, tablet and desktop

Table of contents

What are responsive images?

Before responsive images, you’d include an image on a web page with the trusty <img> tag. Or maybe you’d include a CSS background image, especially for those big full width banners. You’d size that image as best you could based on how large you knew thought it was going to display. But then websites got responsive, devices bred like rabbits and many of them had incomprehensibly high resolutions. So you’d maybe include the highest resolution image possible and hope for the best. Better than clients calling you saying images looked fuzzy.

Including too-big-to-fail images leads to slow page loads, especially on mobile. Think about it – a giant 2,000 pixel wide image is needed to fill a full width banner for a large screen. But sending that same image to a phone just doesn’t make sense. There’s got to be a better way.

By adding two attributes to the <img> tag, a whole range of image can be be shown to the viewer – a large high resolution image size for large high resolution displays and a small, low resolution image size for mobile phones as well as everything in between. No fuzzy images, and no slow page loads. You don’t even have to do a lot of math. World peace.

Responsive images can send a large, high resolution image to a large high resolution monitor and a small, low resolution image to an older smaller phone. Things look crisp on both and each device downloads the image size it needs. Bam!

How do they work?

Here’s where responsive images are really very cool. The exact moment a web page is loaded – even before the CSS and JavaScript have begun to parse – you know two things and the browser knows two things. The things you know, the browser doesn’t. The things the browser knows, you don’t. But if you put those things together, magic happens.

Things the browser knows
Things you know

How big the viewer’s screen is!

What size the images on the server are!

The resolution of the viewer’s screen!

How big the image should appear!

You put the images on the server, so you know how big they are. And you made the website, so you know how big the images should appear. The browser knows none of that because it hasn’t started loading images or CSS yet.

The browser knows exactly how wide the viewer’s screen is and what the screen’s resolution is. You would have no idea about that because you’re not in the room.

All you need to do is tell the browser two things it doesn’t know – srcset and sizes – and the browser uses that missing information along with what it knows and it then does crazy voodoo lots of math to pick the exact image size the viewer needs, nothing more and nothing less. If that doesn’t make you happy, you haven’t used the web for long enough.

The magic of responsive images happens before the browser has started the heavy lifting of loading images and CSS. That’s the whole point. Reduce the file size of images loaded by telling the browser what it needs to know before it starts loading images and CSS.

How to use responsive images

To use responsive images, you modify the <img> tag by adding the srcset and sizes attributes along with the src and alt attributes that were already there.


<img src="" alt="an awesome image">


srcset=" 200w, 400w, 800w, 1600w, 2400w"
sizes="(min-width: 1200px) 1140px, (min-width: 992px) 940px, (min-width: 768px) 720px, (min-width: 576px) 510px, calc(100vw - 30px)"
alt="an awesome image">

That may look like a lot more HTML markup, but compared to the advantages, it’s a small price to pay. And WordPress generates a lot almost all of that for you.

With the srcset attribute, you list all the image size variants the browser can pick from and you tell the browser how wide each image is. In a non WordPress environment, you’d either make all these image size variants by hand or use a cool service like this one to automate it. You’ll have to make size variants for the smallest size on the smallest screen and the biggest size on the biggest screen and a number of size variants in between. WordPress fully automates the creation of the different image size variants, and WordPress generates the srcset attribute for you.

With the sizes attribute, you tell the browser how wide the image appears. Sure, the browser will figure that out eventually after it has loaded and parsed the CSS. The browser needs to know that information now in order to know which image to send to the viewer – by the time it gets to the CSS, it’s too late.

The sizes attribute looks a lot like a CSS media query. You can use mid-width or max-width and you can use calc() functions. You need to write out the widths listed in the sizes attribute for almost all circumstances because you’re the one who made the layout and computer robots aren’t smart enough yet to figure this out for you. WordPress will spit out a default sizes attribute that is better than nothing, but it’s not ideal unless you modify it to be specific about the display width of each image. Examples of how to do that below.

The example above is telling the browser that for viewports 1200 pixels and wider, the image is 1140 pixels wide, then for viewports 992 pixels and wider, the image is 940 pixels wide, then for viewports 768 pixels and wider, the image is 720 pixels wide, then for viewports 576 pixels and wider, the image is 510 pixels wide, then for all other widths, the image is 100% of the viewport width minus 30 pixels.

The src is included as a fallback and for browsers that don’t support srcset and sizes. Most all good modern browsers do, with the exception of crap like Internet Explorer.

The alt attribute is included the same as ever.

So that’s it. Build out some demo layouts and inspect element in Chrome or Safari dev tools. By selecting the image, you can see which image size variant the browser is currently showing. You can also load up websites using responsive images in Google’s PageSpeed Insights and if you’ve done your job properly, you won’t see any warnings about needing to re-size images. In the words of Borat, “Great Success!”

If you’re hand coding websites, then you’re all done – use the responsive image method as listed above and sail on into the sunset with the winds of fame and wealth at your back. If you’re using WordPress, there’s some fun tricks to get WordPress to help you along the way.

To find out the dimensions of your browser on any device, head to What’s My Viewport Size? and to find out the pixel density / resolution, head to What is My Screen Resolution and look for DPR(Device Pixel Ratio).

How to modify WordPress default settings

So responsive images are awesome and WordPress makes them even more awesome. Since WordPress is a content management system, it does a great job of automatically generating different size versions of every image you upload. Those different sizes are automatically listed in the srcset attribute. Score one for making life easier.

WordPress’s implementation of responsive images, however, leaves two main issues for you as a developer to modify if you really want to see the most benefit to page load speed and user experience:

  1. WordPress automatically generates a small handful of image sizes for inclusion in the srcset attribute – including a new size added just for responsive images – but these default out-of-the-box sizes just aren’t enough to get the most benefit out of responsive images in WordPress, particularly for larger full-width displays. You’ll need to modify your functions.php to add additional image sizes based on your website’s display needs
  2. WordPress automatically spits out a default image size for the sizes attribute. While better than nothing, this default size isn’t ideal for nearly all image displays. You’ll need to use one of a few methods to add a detailed sizes attribute to get the most benefit out of responsive images in WordPress

Let’s get into solutions for both.

Increase the number of image sizes WordPress automatically generates

Each time you upload an image to the Media manager in WordPress, multiple versions of the image are created. Without modification, WordPress will make these versions:

  • Thumbnail – a square crop 150 pixels wide by 150 pixels high – called with the_post_thumbnail('thumbnail');
  • Medium – uncropped and resized so the longest side is 300 pixels wide or high – called with the_post_thumbnail('medium');
  • Medium Large – uncropped and resized to 1024 pixels wide – called with the_post_thumbnail('medium_large');
  • Large – uncropped and resized so the longest side is 1024 pixels wide or high – called with the_post_thumbnail('large');
  • Full – original image uncropped and not resized – called with the_post_thumbnail('full');

That’s just not enough sizes to cover modern image needs. A full width image like the top banner on this blog spans the width of all browser windows, and even on a midline laptop, that can be 1,500 pixels wide. At a screen density of 2.0, that’s 3,000 pixels – much more than the stock 1024 pixel wide “large” image size that WordPress creates. In addition to adding larger image sizes, think about any other missing image sizes you may need to display your images.

To add new images sizes, use the add_image_size(); function within the after_setup_theme hook and then give them a name using the image_size_names_choose hook:

================================================== */

add_theme_support( 'post-thumbnails' );

add_action( 'after_setup_theme', 'aw_custom_add_image_sizes' );
function aw_custom_add_image_sizes() {
    add_image_size( 'small', 300, 9999 ); // 300px wide unlimited height
    add_image_size( 'medium-small', 450, 9999 ); // 300px wide unlimited height
    add_image_size( 'xl', 1200, 9999 ); // 1200px wide unlimited height
    add_image_size( 'xxl', 2000, 9999 ); // 2000px wide unlimited height
    add_image_size( 'xxxl', 3000, 9999 ); // 3000px wide unlimited height
    add_image_size( 'portfolio_full', 9999, 900 ); // 900px tall unlimited width


add_filter( 'image_size_names_choose', 'aw_custom_add_image_size_names' );
function aw_custom_add_image_size_names( $sizes ) {
  return array_merge( $sizes, array(
    'small' => __( 'Small' ),
    'medium-small' => __( 'Medium Small' ),
    'xl' => __( 'Extra Large' ),
    'xxl' => __( '2x Extra Large' ),
    'xxxl' => __( '3x Extra Large' ),
    'portfolio_full' => __( 'Portfolio Full Size' ),
  ) );

You’ll need to upload your images again after adding these to your functions.php in order to generate the additional image sizes, or use a plugin to regenerate all image sizes. So it’s a good idea to do this towards the beginning of your development after a bit of testing but before uploading all your images.

Once functions like the above are added, you should see the additional sizes added in the srcset attribute, and you don’t need to do much else in this department.

It’s worth noting that WordPress will automatically add to the srcset all size versions of the image that are exactly the same aspect ratio as the image size specified. So generally – unless your original is a square image – the thumbnail image size won’t be added and other specific crop sizes may not be included.

Add accurate image sizes

WordPress – like the browser – doesn’t know what you know about how wide images will appear. You’ll need to specify accurate sizes attribute in order to get the most out of responsive images. This is pretty important. You can add custom image sizes to the srcset until you’re blue in the fingertips, but if you don’t tell the browser how large the image displays, almost none of it matters.

Out of the box, the default sizes attribute that WordPress displays for every image is (max-width: $width px) 100vw, $width px where $width is the width of the image specified.

This default sizes attribute tells the browser that if the viewport is wider than the image size specified, the image is shown at the width of the image specified, and if the viewport is narrower than the width specified, the image is 100% of the viewport width. This just isn’t accurate except for a very few circumstances. But WordPress has no idea how wide the image is to be displayed – you have to declare this manually with the sizes attribute. If you take away nothing else from this blog post, you need to properly declare the sizes attribute in order to get meaningful results from the responsive image technique.

There are a few methods for fully declaring the sizes attribute:

  1. Declare the sizes attribute inline in each instance of each image displayed
  2. Declare the sizes attribute for each image in each template
  3. Declare the sizes attribute globally for specific image sizes

As with most anything in WordPress, you can use more than one method.

Method 1 – Declare the sizes attribute inline in each instance of each image displayed

We end up using this method the most, possibly out of habit from manually adding the image srcset in non-WordPress environments. This method is easy as each image is laid out manually whether in a single page or in a template loop that gets applied over and over, so going in and adding a manual srcset attribute for each image isn’t a big deal. The concept here is straightforward – before publishing the website live, make sure each instance of an <img> tag has a properly declared srcset attribute. We normally leave out the srcset attribute entirely during development as layouts change. Once all layouts are approved, before publishing the website, we go back and add in all final srcset attributes based on final layouts, then test them all in Chrome developer tools and in Google PageSpeed Insights.

Here’s the typical code we use

$image_id = get_post_thumbnail_id();
$img_src = wp_get_attachment_image_url( $image_id, 'large' );
$img_srcset = wp_get_attachment_image_srcset( $image_id, 'full' );
$img_alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true ); ?>
<img src="<?php echo esc_attr( $img_src ); ?>" srcset="<?php echo esc_attr( $img_srcset ); ?>" sizes="100vw" alt="<?php echo $img_alt; ?>">

In this case, the image is a large image displayed full width, so the sizes attribute is simple – sizes="100vw". You’ll customize this for each image that’s displayed.

The above code snippet is something we use over and over. We set a variable $image_id to store the image’s id, then use that to generate the src using the wp_get_attachment_image_url() function, the srcset using the wp_get_attachment_image_srcset() function and the alt using the get_post_meta() function.

The wp_get_attachment_image_srcset() function accepts a few parameters, one of which is the size of the image to include as the src. This is handy in that the src attribute is a fallback for browsers that don’t support responsive images, so we generally declare a smaller image size because we figure those browsers probably aren’t used on the highest resolution modern displays so they may not need the giantest fallback image. That’s why you see the 'large' size declared rather than the 'full' size in wp_get_attachment_image_url( $image_id, 'large' );.

Likewise, the wp_get_attachment_image_srcset() function accepts a few parameters, one of which is the largest image size to include in the srcset. We generally declare only the largest size needed for each image because why fill up the markup with image sizes that aren’t needed?

Method 2 – Declare the sizes attribute for specific image sizes in specific templates

Another option is to add one or more functions in your functions.php to declare a custom sizes attribute for WordPress to use in place of the overly simplistic default. Here’s what that function looks like:

================================================== */

function aw_custom_responsive_image_sizes($sizes, $size) {
  $width = $size[0];
  // blog posts
  if ( is_singular( 'post' ) ) {
    // half width images - medium size
    if ( $width === 600 ) {
      return '(min-width: 768px) 322px, (min-width: 576px) 255px, calc( (100vw - 30px) / 2)';
    // full width images - large size
    if ( $width === 1024 ) {
      return '(min-width: 768px) 642px, (min-width: 576px) 510px, calc(100vw - 30px)';
    // default to return if condition is not met
    return '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
  // default to return if condition is not met
  return '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
add_filter('wp_calculate_image_sizes', 'aw_custom_responsive_image_sizes', 10 , 2);

This method is useful because you can declare the sizes attribute in one place and let WordPress do the work of applying it over and over. It’s also really useful because it’s the only way to override the overly simplistic WordPress sizes default for images added using the Add Media button in the Post / Pages editor.

In the function above, we’re telling WordPress how large images appear in blog posts – the full size we use for full width images and the medium size we use for half width images. A custom function is created with conditionals and that custom function is used to modify WordPress’s wp_calculate_image_sizes() function.

Using this method, you’d add images to your page template files using a variant on this simple function:

<?php the_post_thumbnail('large'); ?>
Method 3 – Declare the sizes attribute globally for specific image sizes

This methon is really useful for cases where you declare a custom image size and know that image size is always used in a single predictable layout at a single predictable display size. For example, perhaps you need a large image to show full width. You could set that image size using the add_image_size() as described above, then use the following in your functions.php to tell WordPress how large that image size appears everywhere:

function aw_custom_declare_custom_image_responsive_sizes($attr, $attachment, $size) {
  // Full width header images
  if ($size === 'xxxl') {
    $attr['sizes'] = '100vw';
  return $attr;
add_filter('wp_get_attachment_image_attributes', 'aw_custom_declare_custom_image_responsive_sizes', 10 , 3);

This method adds a custom function to the the wp_get_attachment_image_attributes hook to tell WordPress that in every case everywhere that specifies the image size xxxl, the image should appear at 100% of the viewport width. You’d customize that as needed. You can add additional image sizes with additionalelse if conditionals. And as with Method 2 listed above, you’d then add the image into your template files using a variant on this simple function:

<?php the_post_thumbnail('xxxl'); ?>

Whew, that was a lot

Yeah, but it’s awesome because you can significantly reduce the amount of data needed to load pages on your websites while making images look sharp on all devices. Win / win. And WordPress is already set up for responsive images, so with a bit of customization, you can take full advantage of the technology.

Are you using responsive images in WordPress? Are you still awake after all that? Let us know in the comments.


Updated the sizes examples above based on a few of the comments that came in – thanks + keep ’em coming.

blog post author avatar
Written with by Alex Wright

Runs a creative digital marketing, web design and SEO agency in Austin, Texas   |   Likes good looking, fast performing and high ranking websites   |   Doesn't want to understand Snapchat   |   Wants nothing to do with bananas   |   Wishes he were a BMX superstar

42 thoughts on “Responsive Images In WordPress

  1. This is, without any exaggeration, the best article I have ever read on this subject. A very good summary, I learned quite a bit from it. Thanks a lot for sharing… I have added your blog to my feed 🙂

  2. Hi nice article that you’ve wrote over here. A lot to think about and to process.
    But I would like to know your opinion about the following. a) When you let WordPress generates all those image sizes it will consume a lot of storage which can really end up quite high. Isn’t that a big disadvantage to at least mention?

    b) All the sizes that are declared in your functions.php will be set in srcset. But how would you handle the scenario when displaying an image on the overview page of your blog which has a size of lets say 300×150. WIth srcset in place it would also display all the other sizes in the markup right? And it will generate all those sizes while I only want to use lets say 3 variants (small/medium/large for example)

    Hope to hear from you!

    1. Thanks! I don’t think the storage is much of an issue, especially compared to the savings in bandwidth in delivering properly sized images. As to the srcset for images you know are small – yes, you can definitely select the highest size of images to include in the srcset. And this is great to avoid unnecessary markup. You do this like so – $img_srcset = wp_get_attachment_image_srcset( $image_id, 'full' ); – the 'full' there is the largest size of images that WordPress will add to the srcset. So you can put in there a smaller size if you know the image displayed won’t need large images in the srcset.

  3. Thank you, Alex, for this excellent article. It clearly explains the WordPress responsive image capability and how to implement it in code with respect to the ‘srcset’ and ‘sizes’ attributes for use by the WordPress when auto-generating an HTML tag.

    However, I am confused on how to leverage this WordPress capability when creating a WordPress theme from scratch. For example, consider the following scenario. I have this ‘front-page.php’ template:

    I have no custom images defined in my theme at this point. Given my current WordPress 5.5.1 version, WordPress auto-generates seven alternate sized images in my Media Library.

    I used WordPress “Reading Settings” to assign my WordPress “Home” page in the static homepage settings, which maps to the ‘front-page.php’ WordPress Template. The WordPress “Home” page contains nothing but the title, as I want to custom-design it in PHP within the ‘front-page.php’ file. It neither is assigned a featured image nor has it any embedded images in its content. I believe this rules out using “the_post_thumbnail()” function within the context of a WordPress Loop and the “get_the_post_thumbnail()” function otherwise.

    What PHP statement can I place within the tag that (a) allows me to select an image from the Media Library and (b) does so in a manner whereby WordPress loads the appropriately sized image in accordance with viewport size and device context?

    Your reply is greatly appreciated. Thank you.

    1. Heya Anthony! Thanks for the kind words. The situation you mention is perfect for using responsive images, either set via the featured image or set via an Advanced Custom Field that returns an image ID. Here’s code that I use for both of those scenarios. WordPress freaks out with php and html image tags printed in comments, even when wrapped in pre and code tags. So use these variables and then include the img tags shown in the post above with php that echoes these php variables.

      To use the featured image:

      $image_id = get_post_thumbnail_id();
      $image_src = wp_get_attachment_image_url( $image_id, 'large' );
      $image_srcset = wp_get_attachment_image_srcset( $image_id, 'full' );
      $image_alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true );

      To use an image specified by an Advanced Custom Field that returns the image ID:

      $acf_image_id = get_field( 'acf_image' );
      $acf_image_src = wp_get_attachment_image_url( $acf_image_id, 'large' );
      $acf_image_srcset = wp_get_attachment_image_srcset( $acf_image_id, 'full' );
      $acf_image_alt = get_post_meta( $acf_image_id, '_wp_attachment_image_alt', true );
  4. Hello, i hope you are able to help me here. I’m new to wordpress, and very inexperienced with coding, and all the language. I’m having issues with my site and i think what is written here is possibly a solution but my understanding is holding me back knowing where to start.
    I’ve got a basic theme, nothing fancy, and i’m using the recent Godaddy ‘block gallery’ plugin, and a simple image gallery viewer plugin to enable a user to click/swipe through all images in a post.
    My problem is when viewed in the gallery viewer the images are not their best resolution. I know for a fact that the images in my media library are almost all 2560px wide, yet the viewer is showing something perhaps the same size but a much worse resolution.
    I’ve picked up the issue with the gallery viewer developer but they seem to think the issue lies in the html, not in their gallery code.
    Where do i start?!
    i’ve set my large image settings in media settings to 2800px, that hasn’t changed anything.
    I think i need to use your method 2, or 3 but i’m not sure which. method 3 sounds best since my images are almost all the same size in the media library and how they appear on site – and i want the user to see the biggest possible image (feasibly on their browser/device). But, using method 3, if i tell the fuctions.php to use the biggest possible image, will that override the responsive nature of wordpress images, so that users on a phone will get unnecessarily large images?
    Or if you know the issue is actually with the gallery developer please let me know?
    Apologies if this is confusing/long-winded. I’m really trying to get this fixed.
    thanks for taking the time to write this post, and thanks in kind for reading this.

    1. Sorry you’re having trouble, Levi. I don’t think the trouble you’re having will be solved by going through the steps outlined in this blog post. I think the responsive image methods laid out here will only complicate things. If you have a link to share, send that through and I’m happy to take a look.

        1. Hi Levi-

          When I view the website in Chrome and go to the inspector and select the images in your gallery, Chrome is telling me that it is loading up reasonably large size images, for example×1024.jpg and×1365.jpg.

          Your media query in the responsive image markup is in fact wrong, but it’s not causing a problem. Yours says sizes="(max-width: 1536px) 100vw, 1536px which means “If the viewport is smaller than 1,536 px wide, the image is displayed at 100% of the viewport width, otherwise (for viewports larger than 1,536px wide, the image is displayed at 1,536 px wide. The number in here is wrong – it should be 640px which is the real width of your display area. But because it’s wrong on the too large side, you’re lying to the browser and telling the browser that the image is displayed larger than it is, which is causing the browser to load up too large an image, which is good for resolution, but bad for loading speed. If I were you, I wouldn’t do anything about it. The actual images themselves look kind of soft to me, which may be leading to the resolution issue you’re looking at. When I load up the actual originals you uploaded, like, the images look a bit soft. You may want to consider using a sharpening filter online or on Photoshop. Sometimes, images of artwork need more sharpening than you may think to pop when displayed online.


  5. There’s a small typo which should be fixed : “What size the images on the sever are!” => you probably mean *server*.

    Otherwise great post, thanks !

  6. Hey Alex,

    I was reading your article, it is very informative. I would like to suggest you that if you can create simple wordpress plugin to include those functions that will be a great help to the community.

  7. Thanks for your article ! followed your steps and everything’s working fine. But now i’m wondering if there is a way to have two different sets of « add_image_size » depending on the width of the image that is being uploaded ? What i’m looking for is something like :

    “Rule” 1 – If the source image i tried to upload is more than 150px wide, then use this set…

    “Rule” 2 – If the source image is less or equal to 150px, use that set…

    The goal i’m trying to achieve is obviously to avoid very small files on images that are destined to be big. As i’m a beginner in coding this might not be the right way to do it and i’m open to any suggestion !

    Thank you again and have a nice day.


    1. Thanks for the note, Julien. I’m not sure if you’re referring to a php function that would go in functions.php or an HTML markup … something that goes in the sizes markup. Either way, I’m not sold on the effectiveness. We just upload giant size images for everything and let the responsive image setup take care of the rest. Who knows, maybe someone is using a 4x resolution display…

  8. Thank you for your great article! It is a very informative one. I have a travel blog with lots of images, which I would definitely try out your techniques in the future.

    However, I have now encountered a problem, which WordPress is only inserting the automatic “srcset” command for part of the images in my blog. For the other images which are not responsive for unknown reason (all images are inserted to the posts in the same way), WordPress would just directly serves the oversized full size image to the visitors. Do you have any idea what is going on? Thank you.

  9. Thanks for the article! I’m working on implementing your inline method and I can’t figure out why wordpress is still including the default image size in the srcset (it’s around 6000px, don’t really want that loading…ever.) Do you have any insights where that might be coming from?

    1. Hey Garrett – thanks for the kind words. Including the original in the srcset shouldn’t negatively impact performance, as the browser will only use it if necessary. The srcset is just a list of available images. However, if you only want images included in the srcset up to a maximum size, you can specify that with wp_get_attachment_image_srcset( $image_id, 'large' ); instead of wp_get_attachment_image_srcset( $image_id, 'full' ); and you can include other sizes beyond 'large' if you’ve specified custom image sizes in your functions.php. This can be especially helpful to specify custom cropped image sizes.

  10. Hello Alex,
    Thanks for this article.
    Sorry for the question I will ask, I am just a candid beginner trying to optimize the image size for mobile (and that’s how I found your article googling “how to include responsive images in wordpress”).
    Your post is pretty technical, and given I don’t know much about code, I read other articles. And they say that wordpress includes responsive image for a couple of years.
    So I don’t know much what I should think. Is your article still update in 2019 ? Does is make sense to do all that today ? Or does wordpress do it automatically and it’s not needed anymore ?

    1. WordPress ads parts of the necessary code for responsive images. However, in order to make it all work, *you* have to indicate how large the images appear. Neither WordPress nor any plugin nor the browser nor anyone else can know this. So if you use WordPress’s solution out of the box without customizing it, you’re not getting much of any benefit. If you want to properly use responsive image strategies, *you* have to indicate how large the images appear. That’s what most of this article is about.

  11. Thank you this is super super helpful. I still don’t get the sizes that correspond after the actual (min-width). In my case, it seems to never select the proper image but one like twice the width. This tells me it’s the device size, but how do we force images to use the smaller one anyway… have you come across this yourself?

    In Drupal, we can use the picture tag which I prefer because it really forces the browser to choose the proper image source and just works…. but WordPress it’s a bit tougher.

    1. Heya Shane! Can you send examples of an image using the <img> tag with responsive image sizing where the browser is pulling images larger than you think it should? This indicates that either you’ve not written the <sizes> properly or (and most likely) your device pixel density is higher than you may imagine causing the browser to actually properly call a pretty large image to display at the correct resolution for the correct image size.

      To answer your question about “the sizes that correspond after the actual (min-width)” – the size listed at the end of your string of (min-width: XXXpx) YYYpx, (min-width: ZZZpx) AAApx, ... is the image size smaller than the last condition. So for (min-width: 1200px) 1140px, (min-width: 992px) 940px, (min-width: 768px) 720px, (min-width: 576px) 510px, calc(100vw - 30px) the browser is being told that below 576px, the image is 100% of the viewport width minus 30 pixels.

      Send through code you’re having trouble with or an example and I’m happy to lend a hand if I can.

  12. Hey Alex. I’m circling back on your excellent post with another question that’s come up. We mostly use Method 3 for custom image sizes that display in custom post types, which are the primary features of websites we’ve been building (e.g., portfolio, listings, etc). But on a more basic site, where users add images in posts/pages using default images sizes (‘Medium’ or ‘Large’), we discovered this method doesn’t appear to work, right?!? So we tried a modified version of Method 2, and it comes very close to working EXCEPT on portrait-oriented images, where the width is not large enough to trigger properly. Is there a way to get Method 3 to work with default image size names (e.g., Medium or Large)?? We have a question on StackExchange, but no hits.

    1. Hi Kenny-

      Here’s what I use on this site to declare the sizes for images that an author adds to blog posts. This is pretty much the same method as described in Method 2 above. You should be able to adjust the conditional tags to suit your needs. Note that is_singular('post') is more specific than is_single() and can be used to differentiate standard blog posts from posts that use a Custom Post Type. They key is adding to the conditional tags to specify what post type you’re targeting and then add different sizes as needed.

      function aw_custom_responsive_image_sizes($sizes, $size) {
      	$width = $size[0];
      	// blog posts
      	if ( is_singular( 'post' ) ) {
      		// half width images - medium size
      		if ( $width === 600 ) {
      			return '(min-width: 768px) 322px, (min-width: 576px) 255px, calc( (100vw - 30px) / 2)';
      		// full width images - large size
      		if ( $width === 1024 ) {
      			return '(min-width: 768px) 642px, (min-width: 576px) 510px, calc(100vw - 30px)';
      		// default to return if condition is not met
      		return '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
      	// default to return if condition is not met
      	return '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
      add_filter('wp_calculate_image_sizes', 'aw_custom_responsive_image_sizes', 10 , 2);

      Your question about image sizes where the width isn’t large enough to trigger properly is a tough one. So the scenario is that an author uploads an image that is too small to make available an image size that you’ve targeted with your Method 2 rule, then goes to add the image to the blog post but doesn’t use the image size you targeted with your Method 2 rule? I can’t think of an answer to that other than to have authors upload large images for everything and let WordPress do its job of making all the correct smaller sizes.

      Also worth noting for this function posted in this comment and in Method 2 above, I have CSS rules set up to target different image sizes added to blog posts to define the final display size of the image, as there’s not a possibility of adding containing divs to images added to blog posts using the standard WordPress Media Library. But this way, the browser at least knows what size image to load before the CSS is parsed.

      But that doesn’t answer your question, because if the image hasn’t been uploaded large enough to make the correct size available, neither the PHP function or the CSS rule will do anything.

      Let me know if this helps or if I didn’t understand the scenario. And thanks for commenting and the kind words!

  13. Hi

    I stumbled upon this post while tearing my hair out over responsive images. I set up various custom sizes for the images on my site.

    So if you look at the first image on this page

    You will see the code is:

    Then I went to Chrome developer tools and set the browser to Nexus 5 (360 x 640)

    My initial understanding of the srcset was that it would look at the viewport width (I thought it would be 360).

    I thought it would then choose to load one of the resized images (perhaps the 400 x 267).

    However I’m looking at the network tab and it looks like the original full-size image is being used.

    From the comment above I’m presuming the actual viewport width is not 360 and perhaps (360 x 3 – although I’ve no real idea to be honest).

    So my question is, and I don’t mean to be rude, is all this pointless? Or am I misinterpretting something/made an error?

    If I run this page through the Chrome developer (nexus 360 x 640) and look at the network tab, it looks like this image:

    is the one that is actually being loaded, despite the srcset code

    1. Heya David! It looks like the main metro station image on your site is set up with responsive image sizes in the srcset but the sizes is set to the WordPress default which is the size of the image itself, in your case (max-width: 800px) 100vw, 800px and that’s not the correct size. That image (and maybe all your main images) would be sizes="(min-width: 1281px) 730px, (min-width: 960px) 590px, (min-width: 769px) 688px, (min-width: 481px) calc(90vw - 80px), calc(100vw - 40px)" or something close – I just gave it a quick once over. You need to figure out the size of the image display at each breakpoint.

      As to my blog page – it depends on your screen resolution in addition to the viewport width. You can head to this link to see your current device’s pixel density –

      Hope that helps. Comment back with any other questions…

      1. Thanks so much. The penny hasn’t completely dropped yet. But I’ve just worked out where you got the sizes from. I’ll have another bash tomorrow, but it’s a lot clearer now.

        1. Yeah David, for sure keep in touch. Your css media queries use max-width rather than min-width so my sizes could use adjustment for that but hopefully you get the idea.

  14. Great and thorough writeup! I’ve been using these techniques for the last year or two on new sites. Figuring out the various needed sizes, with images going from 3 column, to 2 column, to full width as browser decreases, can be VERY complex and time-consuming. But when done, it is very elegant.

    But I’m wondering if there have been any advances or insight recently about the fact that all this work to ‘supposedly’ deliver smaller images to users on phones may be doing the opposite, due to pixel densities?!? So while I think my iPhone user is going to request my tiny 414px wide image, they may actually request the 1242px+ image because they have a newer phone with 3x pixel density. They may receive larger photos than my desktop viewers on their home fiber connections!


    1. This is a good point, Kenny. That 3x pixel density iPhone should get the 1242px+ image from your site. That iPhone is telling the browser – “my viewport width is an effective 414px wide (or whatever) and my pixel density is 3x, so give me what you got” and in many cases, for mobile devices with high pixel density, that will end up being a larger image than some desktop displays get.

      The idea behind responsive image technology is to give each device what it needs based on the viewport size and pixel density. The idea isn’t to restrict data based on presumed device type.

      In terms of advances / insight, to me the only solution that would work is a universally accepted, user driven browser setting that says “restrict my data, I’m on a slow or expensive connection” so that viewers could announce to websites that they are choosing to request smaller images and other restricted data based on their current connection.

      What do you think?

      1. I agree that the ‘proper’ image is probably being delivered to give the best ‘quality’ experience possible at various breakpoints. I just thought it’s interesting when reading about the reasoning & purpose behind coming up with responsive images in the first place, not serving huge images to people on small devices, which a lot of times also have more limited bandwidth, seems to be the main impetus. I agree it falls the browser to come up with a solution – bandwidth should be taken into equation when choosing proper images. But not sure this will happen. I just don’t think the average viewer is going to be able to tell much difference between that 414px wide vs 1242px wide average photo in most cases, unless they have young eagle-eyes and keep their phone a few inches from their face! So at least ONE of the main goals may have failed to a degree…

        1. Heya Kenny – I totally agree that mobile phones present a difficult dichotomy. On the one hand, they are often connected to expensive metered data connections. On the other hand, they have absurd pixel densities. When you double the pixel density, you quadruple the pixel dimensions of the image. You’re right that the original intention of responsive images may be subverted by ever increasing pixel densities.

          I can personally tell a great deal of difference looking at a lower resolution image on a high resolution display. To me, it’s unfortunate but I really notice the difference. But I don’t like wasting data. So I’m torn as well…

  15. As a web design newbie, I am constantly exploring online for articles that can help my new design business grow. I’ll be on the lookout for more responsive image tips. Thanks!

  16. Thanks for the tips – I had most of the pieces of th e responsive image puzzle but not all. Helped me get faster loading on mobile.

  17. Appreciating the time and effort you put into your blog and in depth information you offer.
    It’s nice to come across a blog every once in a while that isn’t the same unwanted rehashed information. Fantastic read!
    I’ve saved your site and I’m including your RSS feeds to
    my Google account.

Leave a Reply

Your email address will not be published. Required fields are marked *