Open Bug 1786166 Opened 2 years ago Updated 2 years ago

Flexbox container holding an image with set height calculates width incorrectly

Categories

(Core :: Layout: Flexbox, defect)

defect

Tracking

()

People

(Reporter: nick, Unassigned)

References

Details

Attachments

(6 files)

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

Steps to reproduce:

I have a flex-item that is not justified as expected because it's width is incorrectly calculated. Please see attached html for a simple example.

Actual results:

The inner image has a set height which shrinks its width. The flex item around the image stays the full width of the original image.

Expected results:

The flex item should shrink to the width of it's content, and end up centered on the page

The Bugbug bot thinks this bug should belong to the 'Core::Layout: Flexbox' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Layout: Flexbox
Product: Firefox → Core

Thanks for the bug report! I'll post a few additional testcase variants here.

This is a little bit like bug 1785914, except that bug is about the img itself being a flex item which triggers special behavior for flex items with aspect ratios; whereas here, we've got the img inside of a flex item.

Note that the reporter's testcase has two levels of flex containers -- #container and main -- which I'll refer to below. (However, this is reproducible in simpler examples with only a single level of flex container.

I agree with the reporter's expectations, based on flexbox section 9.1 section on definite sizes cases #1 and #3 in the numbered list there. In particular:

  • #main should be considered to have a definite final (post-flexing) height, based on the spec's "case 1", since it's a flex item in a vertical flex container (i.e. height is its main-size), with a definite main-size on its flex container (#container has height:100vh).
  • Because of that, the img's parent-div should also be considered to have a definite height, based on the spec's "case 3", since it's a stretched flex item (it gets align-self:stretch by default) in a single-line flex container with a definite cross-size (height).

So the img's parent div should behave as if it had a definite height. And if I explicitly give it a definite height in its style attribute (e.g. height:158px which is roughly the height that it ends up with on my screen), then it changes to match the reporter's expectation.

Severity: -- → S3
Depends on: 1785914
Attachment #9290766 - Attachment description: flexbox-example.html → testcase 1 (from reporter)
Attached file testcase 2

Here's a reduced testcase.

EXPECTED RESULTS:

  • The black border (flex item) should tightly wrap the teal box (the canvas, which I'm using in place of an img).
  • No red should be visible.

ACTUAL RESULTS:

  • Black border/red-background is much wider than the teal box (400px, this canvas element's intrinsic width)

If I add min-width:0, that prevents us from using an artificially-huge automatic minimum size, which helps a tiny bit. But we still end up filling the flex container's full width when we should not.

(We still presumably resolve the flex-basis:content to be 400px, and we let it shrink from there down to the size of the flex container. But really, given that we have a definite height, we should be able to figure out that the actual content-width is smaller than that.)

(This testcase is just like testcase 2, but now with max-height instead of height on the canvas. Expected/actual results are the same as for testcase 2 posted in comment 3.)

Status: UNCONFIRMED → NEW
Ever confirmed: true
Version: Firefox 103 → Trunk

Here's a reference case, which has the same markup as testcase 2 except that I've added an explicit height:100% to the flex item. This lets us realize that its height really is definite and compute its content-based sizes (min-width and flex-basis) to be the correct/smaller size.

No longer depends on: 1785914
See Also: → 1785914
Attachment #9291255 - Attachment description: reference case (for testcases 2 through 4) → reference case (for testcases 2 through 4): using an explicit cross-size (height) on the flex item

Nick: if you're running up against this in real web content that you're developing, here's one workaround that should match your expected rendering in all browsers (though it may be less applicable depending on how much additional complexity there is in your actual web app).

As compared to your original testcase, I just added these 3 decls to the parent of the img element:

        width: 0;
        display: flex;
        justify-content: center;

The width: 0 declaration effectively nerfs this sizing bug (but breaks the centering of the img by offsetting it to the right of center); and then, the display:flex; justify-content:center restores the centering behavior that you're looking for (instructing the img to overflow equally on both sides from its now-zero-width container).

(For completeness: I found one scenario where Chrome renders your original testcase slightly differently from this one -- it happens when the img is squashed to a very small height, smaller than a line-height. That triggers some special baseline-alignment behavior in your original testcase (due to the fact that the img is inside of a block flow with an automatic line). I suspect that baseline-alignment-to-a-secret-line is not behavior that you care about or want. If you add vertical-align:top to the img in the original testcase, then it removes that special behavior and ends up pixel-for-pixel-identical to this comment's attached workaround, at all window sizes, I think.)

Attachment #9291256 - Attachment description: reporter's testcase with workaround added → reporter's testcase with workaround added (effectively a reference case for testcase 1)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: