Flexbox CSS: 'align-items' not respecting percentage max-width on grandchildren elements




4 years ago
4 years ago


(Reporter: oliverjash, Unassigned)


({reproducible, testcase})

reproducible, testcase

Firefox Tracking Flags

(Not tracked)



(2 attachments)



4 years ago
Created attachment 8501318 [details]
Screenshot 2014-10-07 22.49.01.png

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2181.0 Safari/537.36

Steps to reproduce:

1. Create a flexbox, with styles:

    display: flex;
    flex-direction: column;
    align-items: center;

containing a child `img` element, with styles:

img {
    max-width: 100%;

Actual results:

The img does not respect its `max-width` property. See the scroll bar in the attached screenshot.

Expected results:

The img should respect its `max-width` property. When the viewport is less than the image size, the parent flexbox should stretch/shrink to fill the viewport width, and thus the image size should be 100% of this width.

Chrome behaves correctly.

Example: http://jsfiddle.net/OliverJAsh/65xq3cjn/


4 years ago
Component: Untriaged → Layout
Keywords: testcase
Product: Firefox → Core

Comment 1

4 years ago
dholbert, can you take a look? :-)

(we seem to behave the same on nightly and 33)
Ever confirmed: true
Flags: needinfo?(dholbert)
Keywords: reproducible
Created attachment 8501375 [details]
testcase 1

Here's a reduced testcase, with a 200x100 black image being used as a grandchild of a 50px-wide flex container.
Flags: needinfo?(dholbert)
OS: Mac OS X → All
Hardware: x86 → All
Version: 32 Branch → Trunk
I think Firefox's behavior here is correct.  Importantly, note that there's an unstyled div between the flex container and the image. The "max-width" percentage is resolved against the width of *that div*. (which doesn't have a specified width, so the max-width is initially meaningless) 

Here's what happens:
 (A) During flex layout, we get to the part where we determine cross sizes (the width in this case). That says: "Determine the hypothetical cross size of each item by performing layout with the used main size and the available space, treating auto as fit-content."[1] We have an auto-width, so we treat it as 'fit-content'.

This 'fit-content' width (on our flex item) means we use the maximum of our item's min intrinsic width and another expression[2], so it's at least as large as our minimum intrinsic width, which in this case is the intrinsic width of its sole child, the image.  (This would be smaller if the image's max-width had something to resolve against, but it doesn't [yet].)  So, the width we end up with the flex item having the intrinsic width of the image.

(B) After we lock in this size, we actually perform layout in the flex item, and its img *now* a something to resolve its max-width against, since we've now resolved a cross size for the flex item.  If the image has max-width:100%, then it'll just keep its intrinsic size. If it's 50%, then it'll be 50% of its intrinsic width; etc.

[1] http://dev.w3.org/csswg/css-flexbox/#algo-cross-item
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/width#Values

I don't know exactly what Chrome is doing here, but I think it's incorrect. IE11 matches Firefox's behavior, too, for what it's worth.

You should be able to get the behavior you want in IE11 and Firefox if you give the flex-item a max-width -- e.g. in your jsfiddle:
 .foo  { max-width: 100% }

Here's the modified fiddle: http://jsfiddle.net/65xq3cjn/1/

Resolving as INVALID since I think what we're doing is correct; I'll file a bug on the Chrome behavior, and perhaps reopen this if we get a compelling argument from the Chrome folks that their behavior is actually correct (or if such an argument surfaces here.) Thanks for filing the bug!  Always good to discover compat issues as early as possible...
Last Resolved: 4 years ago
Resolution: --- → INVALID
(Updating summary with s/children elements/grandchildren elements/, because in this case the max-width is on a grandchild, which per previous comment, makes all the difference. Notably, if you *do* add a max-width on the *child* element (the flex item), then you get the expected results, as shown in my updated jsfiddle.)

I filed https://code.google.com/p/chromium/issues/detail?id=421255 on Blink's behavior here.
Summary: Flexbox CSS: `align-items` not respecting percentage max width on children elements → Flexbox CSS: 'align-items' not respecting percentage max-width on grandchildren elements

Comment 5

4 years ago
Thanks for that information, Daniel. The fix you suggested works in Chrome, but not in IE11 unfortunately. What's the story there?
It works for me in IE11. (using my modified fiddle from comment 3)  Maybe you just loaded the wrong fiddle?

Anyway, if it's not just a mistake, I think you're on your own for figuring out how to get things working how you'd like in IE11 -- I don't run windows as my main operating system, so testing IE is difficult for me.

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