Image width/height from fallback breaks responsive images

Created on 1 April 2025, 26 days ago

Problem/Motivation

Responsive images using srcset and sizes image attributes default to the fallback's image dimensions for the width/height of the <img> tag.

When the width and height of the image defaults to the fallback image dimensions, this overrides any settings in responsive image styles where we provide a set of image styles along with the estimated dimensions images should be rendered at.

The issues the current behavior creates includes rendering images at the wrong size due to the fallback image. I typically select a small-to-medium image as fallback image which is hardly ever the size of the image being rendered.

Steps to reproduce

  1. Use Drupal 10.4+
  2. Create any image styles if necessary or use the existing image styles you may already have
  3. Configure a new Responsive Image Style using Responsive images from the Breakpoints group dropdown
  4. Choose "Select multiple image styles and use the sizes attribute." from the Type fieldset
  5. Select as many image styles as needed
  6. Type the desired sizes value in the Sizes field (i.e. (min-width:768px) 720px, 100vw))
  7. Select a fallback image (preferably an image that is not the size of how you expect your image to render)
  8. Create page where the new responsive image style is used and add images to it. Save it
  9. Your image should render using your fallback image dimensions

See attached screenshot.

Proposed resolution

Restore original responsive image rendering behavior which allowed images to be rendered at the size specified in the Sizes field.

Review this issue https://www.drupal.org/project/drupal/issues/3377420 πŸ› Responsive image width/height values are not used from fallback image style Needs work which seems to be where the new behavior stems from. Perhaps rethink the approach for ensuring the img tag dimensions reflect the correct image's dimensions, not the fallback image.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Active

Version

10.4 ✨

Component

responsive_image.module

Created by

πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mariohernandez
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    I did additional research and testing using vanilla installations of Drupal 10.x.

    First test - Using fallback image width and height

    Expected behavior, image should render large on desktop (max 1290px), and full width on mobile.

    1. First I configured responsive images (resp-img.png)
    2. While inspecting the image, visually it looks tiny and that's because it is using the fallback image dimensions (dimensions.png)
    3. However, looking at the Network tab in the dev tools, we see the right image is loaded, but because Drupal is changing the width and height of the img tag based on the fallback image dimensions (network.png)

    Second test - Not using fallback image

    1. Same responsive image configuration as above
    2. Inspecting the image this time, reveals the right width/height on the image tag which is provided by the Sizes configuration in item #1 above.
    3. The Network tab in inspector's console displays the right image dimensions and visually the image also looks correct (dimensions2.png)

    Conclusion

    Drupal is able to provide the right width and height to the img tag without resourcing to the fallback image. Hoping this can be resolved to be able to effectively use responsive images.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡³πŸ‡ΏNew Zealand quietone

    Changes are made on the main development branch 11.x first, then backported.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States agarzola

    The question is how to determine which image to use for these values. Which image is most correct to use? From a progressive enhancement perspective, the fallback image seems like the correct choice, even though it creates the issue described here for images that are not sized with CSS.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    @agarzola, that a great question and that's the beauty of using srcset and sizes image attributes. The srcset lets you define a set of images each which includes its width, allowing the browser to select the best image based on its width and the desired rendering size which is provided as part of the sizes attribute.

  • πŸ‡ΊπŸ‡ΈUnited States agarzola

    Yes, that part is clear. What I am asking is what width and height attributes should be included in the img tag. Of all the inages included in the srcset, which one should Drupal use use to populate those attributes?

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    @agarzola, I see what you mean. I think the width/height should be the one from the image selected by the browser. The browser analyzes the srcset and sizes attributes values then picks the best image that meets the rendering criteria, among other things. Up to this point, this has been the default behavior until I started seeing issues with fallback image width/height being applied to the img tag (thus this issue). By the way, this only seems to be an issue with srcset/sizes and not <picture>.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    This patch removes the fallback image dimensions so they are not forced into the width/height attributes of the img tag.

  • πŸ‡ΊπŸ‡ΈUnited States agarzola

    I think the width/height should be the one from the image selected by the browser.

    I'm asking about the HTML attributes that are printed by Drupal in the HTML payload, not the rendered width and height in the browser. There needs to be some value in the width and height attributes. What values should Drupal use for those attributes if not the values from the fallback image?

    This patch removes the fallback image dimensions so they are not forced into the width/height attributes of the img tag.

    Removing the width and height attributes as proposed in #17 will cause content layout shift issues that were resolved in 3359421 πŸ› (Re-)Add width / height also on fallback image Fixed . Is that really what we want?

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    Yes @agarzola, my answers remains the same. The width/height values for the HTML attributes should be those of the image selected by the browser. My argument is that what is the point of configuring responsive images with specific loading criteria, if they will be overriden by using fixed values from a fallback image?

    As for issue 3359421 πŸ› (Re-)Add width / height also on fallback image Fixed , If thats where the breaking changes were introduce, then I would think they need to be implemented differently.

    I appreciate your feedback and I hope with the help of the community we can come up with a solution that will work for everyone while adhering to the standards of responsive images.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Patches should be in MR, and most likely will need a test case showing the issue.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    Hey there! I wanted to share some clarifications about this patch that might be helpful:

    1. Just a friendly reminder that the fallback image isn't meant to be your primary image solution. It's simply a safety net for browsers that don't support the srcset and sizes attributes (which is quite rare these days!). Since all major browsers have supported these features since 2017 (you can check out https://caniuse.com/?search=srcset for details), you probably won't need to rely on the fallback much at all.
    2. When you're using srcset and sizes, the browser automatically handles the image's width/height values. Each image in the srcset includes its width information, which helps the browser make smart decisions and apply the right dimensions to the image tag.
    3. When we force responsive images to use fallback image dimensions, we're actually undoing all the benefits of responsive design. The whole point is to let the browser choose the best image based on the user's device, screen resolution, and network conditions. By forcing a specific size, we're essentially going back to the pre-responsive era when we had to use one-size-fits-all images.
    4. If you're noticing layout issues, it might be worth revisiting your overall layout strategy. Ideally, your markup and CSS should work together to create flexible layouts for different breakpoints, with images naturally fitting their containers. A simple CSS rule like img { height: auto; max-width: 100%; } can ensure images never exceed their containers. Remember that your layouts should determine how images appear, while responsive images deliver the most appropriate file for each situation.

    I hope this helps understand what's in play here.

  • πŸ‡ΊπŸ‡ΈUnited States DamienMcKenna NH, USA

    Could you please clarify what the HTML looks like before and after this change? I think that would help everyone understand what is happening. Thank you.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    @damienmckenna, certainly. The HTML does not look much different before/after the patch is applied. I've cleaned it up for better readability.

    Before

    <img loading="eager" 
      srcset="small.webp 360w, medium 480w, large.webp 768w" 
      sizes="(max-width:768px) 100vw, 720px" 
      width="480" 
      height="360" 
      src="medium.webp" alt="Image alt text">
    

    After

    <img loading="eager" 
      srcset="small.webp 360w, medium 480w, large.webp 768w" 
      sizes="(max-width:768px) 100vw, 720px" 
      width="768" 
      height="512" 
      src="small.webp" alt="Image alt text">
    

    The difference after the patch is applied is that the width and height of the img tag is set/forced to be that of the fallback image rather than using the dimensions of the image the browser has selected. As you can see, each image in the srcset has a width defined (i.e. 768w, this value is to instruct the browser how big this image is and in combination with the query in the sizes attribute, the browser is able to select the best image to meet the developer's intended rendering goal.
    By using the fallback image dimensions as the img width/height, we are bypassing the concept of responsive images.

    Here are before/after screenshots which show the issue when the fallback image is smaller than the size of the intended image. Some may say: "Why not use a larger fallback image?", true, but again, the whole goal of responsive images is for the browser to analyze the environment and select the best image for the job. In addition, what if I am dealing with an image that is, say, 2600px? this means my fallback image would need to be that large which I don't think is the best approach.

    Before

    After

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles
  • πŸ‡ΊπŸ‡ΈUnited States DamienMcKenna NH, USA

    I wanted to know what the recommended solution was for the "width" and "height" attributes when using responsive images.

    I couldn't find any recommendations on Mozilla's dev article on the topic or their <img> docs page.

    I did find this article:

    The article says "Set width and height to the resolution that corresponds to your default src." That suggests that Drupal core's handling of these attributes is correct and that we should close this as "won't fix".

  • πŸ‡ΊπŸ‡ΈUnited States DamienMcKenna NH, USA

    BTW it's not technically possible to set the image's width and height attributes to the specific image variation the browser will use as the HTML tag is generated at the server, and the server doesn't know what the browser is going to do with it.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    Yes, this is not an easy issue due to your last point of the server not knowing what the browser will do.
    This may be a silly question, but based on the code examples in my previous comment, how were the width/height set?

    As far as the browser selecting the best image, we provide a list of images to the browser and let the browser know how big each image is using the `w` descriptor. Then in the sizes attribute we tell the browser how big/small we want the image to be rendered allowing the browser to select the best image based on viewport width, screen resolution, network speed, etc.

    In my opening comment at the beginning of this issue you will see a screenshot for the configuration I just described. However, in my code example in the previous comment, the width and height values are present in the img tag. How did they get there? Was that Drupal after the page was rendered?

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    On smaller images, using a fixed image may work just fine and we wouldn't even need responsive images. This is the approach I take when images are intended to be rendered at a relatively small size across all breakpoints. However, when it comes to large images such as Hero images or full width images, this is when responsive images shine and using the fallback image approach would result in either upscaling images with CSS which is not recommended, or, using extremely large images as fallback which in turn will affect performance and maybe even UX.

  • πŸ‡ΊπŸ‡ΈUnited States DamienMcKenna NH, USA

    IMHO a major part of this is the CSS that goes with the image, so in the examples in #23 there might be CSS that also affect how the image is being displayed.

  • πŸ‡ΊπŸ‡ΈUnited States mariohernandez Los Angeles

    The two ways in which CSS is involved include:

    1. Using the following global rule: img { max-width: 100%; height: auto; }. This rule is pretty much best practice on most projects. It ensures the image never exceeds the width of the container it is in, and the image width will never be upscaled beyond its original image size.
    2. Other part where CSS plays a bigger part is in layouts. With the CSS rule above, the image will work in most cases as long as your layouts have been properly established using any of the available methods such as CSS Grid, Flexbox, plain'ol dimension settings on containers.
    3. Using CSS' aspect-ratio property can help the browser predict what the image approx size or aspect ratio will be.

    It's not common practice to resize the actual <img> tag only using CSS. The recommended approach is to manage layouts around the image and images should naturally adapt to the layout containers.

    The last point about using CSS for image dimensions, yes, it is true that you can actually resize images to the desired dimension with CSS, but just like images, CSS also need to be fully available during the page load process for those rules to kick in.

    I feel like the issue is not so much the size of the image, the browser is already taking care of that for us, but just as important, is assigning the right width/height values to the img tag at load time (ideally the same dimensions the browser selected), to avoid affecting Largest Contentful Paint

Production build 0.71.5 2024