Make WordPress Core

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#35128 closed defect (bug) (worksforme)

Srcset may include a much-too-large image, apparently no way to set size in context

Reported by: programmin's profile programmin Owned by: joemcgill's profile joemcgill
Milestone: Priority: normal
Severity: normal Version: 4.4
Component: Media Keywords:
Focuses: Cc:


While srcset is great for showing the relevant sized image, it may often grab an image that is actually much too large for the space it shows in.

For example, WP outputs this html for a certain image:

<img class=" wp-image-3279 aligncenter" src="" alt="Worship" width="515" height="386" srcset=" 300w, 1024w, 1502w" sizes="(max-width: 515px) 100vw, 515px">

however, due to a special enclosing div, this particular one is displayed within 323x243. The network inspector shows it's actually grabbing the 768 image.

Can we have a way to fix this, at least give themes a way to say for example, images that are within the post-content .span4 element will be max-width of 323?

Change History (8)

#1 @joemcgill
7 years ago

  • Component changed from General to Media
  • Owner set to joemcgill
  • Status changed from new to reviewing

Hi @programmin,

Thanks for the report. Can you tell me more about how this particular image is displayed?

  • If it's added through the content editor, how are the grid containers being created (e.g., shortcodes, etc.)?
  • If it's through a custom admin interface in the theme, can you take screenshots of the interface and share a snippet of the theme code that is used to output the image?
  • If it's generated on the front end through template tags like wp_get_attachment_image() or the_post_thumbnail(), could you share the code you're using?


#2 @programmin
7 years ago

There are a few issues here -

When you insert a huge image at full-size, you get the native height= and width= attributes on image tag. Even if the space it will fill has max-width and styling that makes a much smaller width.

I see there's a the_content filter call to wp_make_content_images_responsive() that calls wp_image_add_srcset_and_sizes() which looks at height and width of img tag.

If I have an image within a div that ends up 1/3 or 1/4th of the post display, do I really have to make some goofy regex to search for the <div class="mythirdsection"> ... images... </div> in the post-content and change the heights, widths before the_content (default 10 priority) runs?

#3 @joemcgill
7 years ago

Hi again,

For situations like these, there is a filter included in wp_calculate_image_sizes() that passes the image dimensions, src URL, attachment metadata, and attachment id. These can be used to change the sizes attribute based on the layout size of your image at different breakpoints.

It's hard to tell without more information whether this filter would be sufficient for your use case. From your comment above, it sounds like your writing the HTML for your grid directly inside the post editor, which may complicate things a bit, but I believe it should work. You can see a couple of usage examples for the wp_calculate_image_sizes filter on this GitHub page.

#4 @programmin
7 years ago

It seems odd that the parameters for that filter have arguments for sizes and attributes of the image, but not what the enclosing html was.

Unless every image in a specific type of post will have the same width/maxwidth properties, or you want to change size attributes based on the image, not the size of where it is placed this doesn't really help. Perhaps a 'pre-html' attribute could be added to that filter so we could see if the html post-content just before the image-tag was '<div class="smaller-area">' for example.

#5 @programmin
7 years ago

Here's an easily testable case where it uses massively more bandwidth, not less, using srcset:

Go and insert a big image on a page, but choose "medium" size. You'll see a medium-sized image in the editor.

Now grab a resizer, and make it just a few pixels bigger. After saving you will see something like this in the page html:

<img class="alignnone wp-image-535 " src="http://localhost/wordpress/wp-content/uploads/2014/10/ffe2b73ac2dd5272-300x225.jpg" alt="" width="303" height="227" srcset="http://localhost/wordpress/wp-content/uploads/2014/10/ffe2b73ac2dd5272-300x225.jpg 300w, http://localhost/wordpress/wp-content/uploads/2014/10/ffe2b73ac2dd5272.jpg 1024w" sizes="(max-width: 303px) 100vw, 303px">

The browser (Chromium 47 at least) decides that it will download the 1024x768 image, not the more appropriate medium image, just because the chosen size is a few px more than the medium image. Maybe this is a browser bug more than a WP bug, but this will be affecting numerous blog viewers.

#6 @programmin
7 years ago

Chromium project says the bug is more that there are not very many images, and there should be more image-sizes available to choose from. Can we have more intermediate image sizes added in the future to prevent this problem?

#7 @joemcgill
7 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from reviewing to closed

Hi @programmin,

Apologies on the delay in responding to your ticket. You're correct that the best way for theme authors to adjust for use cases where an available image size is slightly smaller that what the browser needs, is to modify the sizes of images WordPress creates on upload and/or add additional sizes using add_image_size() which fit the needs of your theme. Since srcset and sizes are evaluated by browsers, and we have no way of impacting the way browsers choose to implement their source selection process, this is probably the best we can do.

If you need to use the wp_calculate_image_sizes filter differently on particular layouts, I would consider either adding the filter from within your custom template, or being creative with which conditional tags you check before applying the filter. For example, if you only want to apply the filter on the front page of the site, you could do something like:

// Only add the filter on the front page of the site.
if ( is_front_page() ) {
  add_filter( 'wp_calculate_image_sizes', 'my_homepage_srcset_filter', 10, 2 );

function my_homepage_srcset_filter( $sizes, $size ) {
  // Add function logic here.

Since WordPress doesn't know anything about your intended markup when this function is called, it's best if this kind of filtering/customization is handled by theme authors. We also have to be careful about creating a bunch of new image sizes out of the box due to the fact that many WordPress users are on shared hosting with limited resources. I'm going to go ahead and close this as a worksforme for now, but feel free to continue the conversation or reopen if you have a use case that you don't believe can be resolved using the current set of tools available and we can reevaluate. Thanks again.

#8 @kerepes.andras
7 years ago

#37546 was marked as a duplicate.

Note: See TracTickets for help on using tickets.