Open Bug 1905511 Opened 4 months ago Updated 3 months ago

Firefox treats images as no intrinsic size rather than zero intrinsic size when loading / lazy-loading

Categories

(Core :: Layout, defect, P3)

Firefox 127
defect

Tracking

()

People

(Reporter: kharelbarun, Unassigned)

References

Details

Attachments

(5 files, 1 obsolete file)

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0

Steps to reproduce:

  1. Open the attached HTML file in Firefox 127.

  2. Hard refresh the page using Ctrl + F5 keys to prevent loading image from cache.

  3. Scroll horizontally

  4. While scrolling, the height of element with blue background (image-list) decreases.

  5. Soft refresh the page using F5 key to load image from cache

  6. This time, the height of element with blue background remains same when scrolling.

About the attached HTML file and the bug:

  • This file contains multiple images laid out horizontally.
  • The images are lazy loaded using loading="lazy".
  • It uses flex to lay out horizontally but grid or float can also be used by uncommenting the relevant code inside <style>.
  • The width and the height property of <img> uses auto but the problem also occurs when using initial, revert, unset
  • The bug does not occur when there is no explicit width and height of <img>. Having no explicit width property should be same as having width: auto but that does not seem to be the case.
  • I have also checked this bug in Firefox 128 Developer Edition and it occurs in that version as well.

Actual results:

The dimension of 3rd and 4th image-list-item changes during scrolling which causes the height of image-list to change.

The height of 3rd image-list-item is 1850px when descendant <img> is not loaded.
The height of 3rd image-list-item is 100px after descendant <img> is loaded.

The height of 4th image-list-item is 0px when descendant <img> is not loaded.
The height of 4th image-list-item is 100px after descendant <img> is loaded.

The width of 4th image-list-item is 0px when descendant <img> is not loaded.
The width of 4th image-list-item is 100px after descendant <img> is loaded.

(When <img> are not loaded) The dimensions of 3rd and 4th image-list-item are calculated using aspect-ratio of descendant <img>. Thus, 3rd image-list-item is 1850x1850 and 4th image-list-item is 0x0 since the <img> are 100x100.

Expected results:

The height of 3rd image-list-item should be 100px even when descendant <img> is not loaded.

The height of 4th image-list-item should be 100px even when descendant <img> is not loaded.

The width of 4th image-list-item should be 100px even when descendant <img> is not loaded.

Attachment #9410334 - Attachment is obsolete: true

I'm a bit confused about how this works in Chromium fwiw. If you remove the src attribute (which is ~roughly what should happen while lazy-loading) then it works like Firefox.

Maybe they're not mapping the aspect-ratio if there's no image loaded or something? That feels super-weird. Or maybe the auto 100 / 100 value is behaving differently if there's an image? That's also super-weird...

What I have understood so far is that lazy <img> that are not yet loaded have dimension similar to eager <img> when source image is being requested but not yet loaded. This can be observed in both Firefox and Chrome.

When both width and height CSS properties are auto (or initial, revert, unset):
In Firefox, eager <img> in such state occupies full width available to ancestor block element. Thus, lazy <img> also occupies full width.
In Chrome, eager <img> in such state does not occupy any space. Thus, lazy <img> also does not occupy any space.

However, I have not found any specification on how <img> in such state are to be styled.

If you open the attachment dimension-of-eager-loaded-image.html and open the console, you can see that:
In Firefox, dimension of <img> is initially 500x500 and then changes to 100x100.
In Chrome, dimension of <img> is initially 0x0 and then changes to 100x100.

This attachment is a better example of this bug in real world projects.

Here, I am using Owl Carousel to show slideshow of images.

OwlCarousel applies width: 100% to <img>. This causes image to get stretched horizontally. So, I have to use width: revert to have width as if no width: 100% was applied. auto, initial, unset also have same effect as revert in this case.
I have also applied height: auto as it is a common practice to do so.

When page is hard refreshed, there will be a huge gap between image and navigation dots. User has to scroll down to see those navigation dots. Even after user slides through all images, the problem still persists as OwlCarousel creates clones of slideshow items that are never shown to user, thus prevents height from returning to normal. Only after soft refreshing the page, the huge gap is gone.

A workaround is to remove height: auto as it is not required in this case. But, it is not easy to notice that. It is common practice to do add height: auto whenever width is used. At the beginning of project, <img> usually does not have loading="lazy", and everything works fine. But, later when loading="lazy" is added, suddenly slideshow is occupying more space than needed.

(This problem might occur in other slideshow/carousel plugins where width: 100% is applied by default but I have not checked yet.)

The severity field is not set for this bug.
:emilio, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(emilio)
Attached file Reduced test-case.

So the question is basically, why do we stretch the item for the second image but not the first?

The answer seems to be "because nsImageFrame::ShouldUseMappedAspectRatio returns true".

I think what's going on is that this check is no longer needed (it was added all the way back in bug 1547231, but since then we've made a lot of changes to how aspect-ratio works).

I'm fairly convinced that that's what's going on because an equivalent SVG that has no intrinsic size but an intrinsic ratio is stretched in both Firefox and Chromium.

Our behavior is consistent with <video> tho, and Chrome still hasn't fixed https://github.com/w3c/csswg-drafts/issues/7524 / this test :(

Flags: needinfo?(emilio)
Attachment #9413986 - Attachment mime type: text/plain → text/html

WebKit doesn't seem to stretch no-aspect-ratio SVGs at all :(

Severity: -- → S3
Priority: -- → P3
Summary: <img> with loading="lazy" and both width and height property set to auto causes dimension of ancestor to be miscalculated until the <img> becomes fully loaded → Firefox treats images as no intrinsic size rather than zero intrinsic size when loading / lazy-loading

This check should no longer be needed (it was added all the way back in
bug 1547231, but since then we've made a lot of changes to how
aspect-ratio works).

I'm fairly convinced that that's what's going on because an equivalent
SVG that has no intrinsic size but an intrinsic ratio is stretched in
both Firefox and Chromium.

I filed the issue mentioned above. The patch on our end is trivial I think, posted it for reference (will need a test).

https://treeherder.mozilla.org/jobs?repo=try&revision=ae341adf52a93fcae17f5b8e14a3cc3b6c9a35b3

Status: UNCONFIRMED → NEW
Ever confirmed: true

So the question is basically, why do we stretch the item for the second image but not the first?

The first image (<img width="100" height="100">) in the attachment does not have src attribute and therefore is not within the scope of this bug.

The question is why the second image (<img width="100" height="100" src="http://software.hixie.ch/utilities/cgi/test-tools/delayed-file?pause=10&amp;mime=image/jpeg&amp;text=z">) and the fourth image (<img width="100" height="100" src="https://www.software.hixie.ch/resources/images/sample">) have dimension 300x300 when the images are being requested. Why are they not having dimension 100x100 according to width and height attributes. While Chrome's implementation of having dimension 0x0 maybe more appropriate than 300x300, I am not sure whether that is according to the specification.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: