Open
Bug 1179454
Opened 10 years ago
Updated 3 years ago
Flex-basis not respected when intrinsically sizing nested flex items
Categories
(Core :: Layout, defect)
Tracking
()
NEW
People
(Reporter: warcraftthreeft, Unassigned)
References
(Depends on 1 open bug)
Details
Attachments
(1 file, 1 obsolete file)
334 bytes,
text/html
|
Details |
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Build ID: 20150525141253
Steps to reproduce:
Sorry the non-descriptive title. Here is a somewhat minimal test-case that I noticed this with:
http://jsfiddle.net/rwv0x1wv/7/
HTML:
<!-- flex: 1 1 auto; flex-direction: row; -->
<ul class="horizontal-container">
<!-- flex: 0 0 10px; min-width is auto by default which is what we want. flex-direction: row; -->
<li>
<!-- flex: 1 1 auto; flex-direction: column; -->
<ul class="vertical-container">
<!-- flex: 1 1 auto; -->
<li></li>
<!-- flex: 1 1 auto; flex-direction: row; -->
<li>
<!-- flex: 1 1 0px; min-width: 0; So the inner li should overflow. flex-direction: row; -->
<ul class="horizontal-container-shrink">
<!-- flex: 1 1 auto; -->
<li>Hello World</li>
</ul>
</li>
</ul>
</li>
<li></li>
</ul>
CSS:
* { margin: 0; padding: 0; }
ul { list-style: none; }
html
{
height: 100%;
display: flex;
flex-flow: row nowrap;
}
body
{
flex: 1 1 0px;
min-width: 0;
display: flex;
flex-flow: row nowrap;
}
.horizontal-container
{
flex: 1 1 auto;
display: flex;
flex-flow: row nowrap;
}
.horizontal-container > li:first-child
{
flex: 0 0 10px;
display: flex;
flex-flow: row nowrap;
}
.horizontal-container > li:last-child
{
flex: 1 1 auto;
background-color: #f00;
}
.vertical-container
{
flex: 1 1 auto;
min-width: 0px;
display: flex;
flex-flow: column nowrap;
}
.vertical-container > li:first-child
{
flex: 1 1 auto;
}
.vertical-container > li:last-child
{
flex: 1 1 auto;
display: flex;
flex-flow: row nowrap;
}
.horizontal-container-shrink
{
flex: 1 1 0px; /* This is not applied! Should shrink to 10px which is minimum basis that isn't auto. */
min-width: 0; /* Neither is this */
display: flex;
flex-flow: row nowrap;
overflow: hidden;
}
.horizontal-container-shrink > li
{
flex: 0 0 auto;
white-space: nowrap;
background-color: #00f;
}
Actual results:
The ".horizontal-container-shrink" in the example has a flex-basis of 0 which should make the inner li shrink if any parent tag has a flex-basis that isn't auto and is less than the auto width. The ".horizontal-container > li:first-child" is a direct parent of ".horizontal-container-shrink" and has flex-basis set to 10px which is less than auto so the ".horizontal-container-shrink" should shrink to 10px and its inner li tag would overflow its parent since it has flex: 0 0 auto; and has nowhere to go.
What happens in Firefox currently is ".horizontal-container-shrink" is behaving as if it has flex: 1 1 auto; forcing its parent ".horizontal-container > li:first-child" to be the same width as itself rather than 10px.
Expected results:
The ".horizontal-container-shrink" tag needs to be 10px.
View Chrome, IE11, or Microsoft Edge for the correct result.
Reporter | ||
Updated•10 years ago
|
Component: Untriaged → Layout
Product: Firefox → Core
![]() |
||
Comment 1•10 years ago
|
||
I get the expected result if I style, in the above testcase, ".horizontal-container > li:first-child" with "min-width: 0".
Without that, it has a min width equal to intrinsic width, so it's possible we're getting its intrinsic width wrong. Daniel, can you check that part?
Note that the min-width being equal to intrinsic width thing is new in the spec and last I checked IE didn't implement it yet. Chrome does in some cases, but it's pretty buggy so far.
Flags: needinfo?(dholbert)
Comment 2•10 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #1)
> Note that the min-width being equal to intrinsic width thing is new in the
> spec and last I checked IE didn't implement it yet.
MS Edge does implement it (and it's available on BrowserStack now, BTW). In this case, it seems to agree with Chrome. Taking a look...
> I get the expected result if I style, in the above testcase,
> ".horizontal-container > li:first-child" with "min-width: 0".
At first glance, it seems to me like that should be required here, or else that element (which is a flex item) won't shrink below its min-content size, yeah.
The question is, is it correct that we're deciding the min-content size of that element (.horizontal-container's first child) is the width of its "hello world" descendant?
I suspect the Chrome/Edge behavior here might be correct, & might be a result of the new flex-container intrinsic-sizing spec text, which we need to update to (per bug 1055887). Right now, we're calculating the min-content width of each nested flex container in this testcase by asking its children what their min-content widths are and summing them; but we should really be doing something a bit more flexy, per http://dev.w3.org/csswg/css-flexbox-1/#intrinsic-sizes .
Comment 3•10 years ago
|
||
I think this is effectively a reduced testcase for this bug, with two nested flex containers around an element with a small flex-basis & wide content.
We strictly honor the "min-width:auto" and shrinkwrap the content all the way up.
Chrome (dev channel) & Edge both display this differently than we do, and differently from each other -- one of them makes the inner item shrinkwrap the content and the middle flex container be skinny, while the other makes the inner item skinny and the middle flex container as wide as the content.
I emailed biesi & Greg Whitworth @ Microsoft with a jsfiddle to see if they know what's going on & think their results are correct. (For now, I'm pretty sure we're correct.)
Flags: needinfo?(dholbert)
Comment 4•10 years ago
|
||
(sorry, attached wrong file; here's the testcase I meant to attach. jsfiddle version also available at https://jsfiddle.net/yojjjt9a/ )
Attachment #8628901 -
Attachment is obsolete: true
Reporter | ||
Comment 5•10 years ago
|
||
Your simplified test-case doesn't include the problem I pointed out. It does help to simplify it though.
http://jsfiddle.net/eeo76ca3/1/
HTML:
<div class="outerFlex">
<div class="midFlex">
<div class="innerFlex">
<div class="text">Hellooooo</div>
</div>
</div>
</div>
CSS:
.outerFlex
{
display: flex;
width: 200px;
border: 2px solid black;
}
.midFlex
{
flex: 0 0 10px;
display: flex;
border: 2px solid red;
}
.innerFlex
{
flex: 1 1 0px;
min-width: 0;
display: flex;
}
Notice that .innerFlex has a flex-basis of 0 and a min-width of 0. This is being ignored by the parent. .midFlex has by default min-width: auto which should evaluate to 0px since it's child has a flex-basis of 0 and min-width of 0? I'd expect the red region with be 10px.
Comment 6•10 years ago
|
||
(In reply to warcraftthreeft from comment #5)
> Your simplified test-case doesn't include the problem I pointed out.
My point was that rendering engines already render this differently, even without "min-width:0". (Chrome & Edge are clamping one or both inner elements, regardless of "min-width:0", at least in this simplified testcase)
But you're right, your main issue may boil down to something distinct from that cross-browser difference.
> Notice that .innerFlex has a flex-basis of 0 and a min-width of 0. This is
> being ignored by the parent.
Ah -- so in this case, I think this is an instance of bug 972595 -- we're incorrectly using the "width" of the flex container (midFlex) when determining its intrinsic width. If you change "flex: 0 0 10px" on midFlex to "flex: 0 0 auto; width: 10px", then we give expected results.
demo: https://jsfiddle.net/eeo76ca3/3/
Comment 7•10 years ago
|
||
Indeed, this was the problem in the initial jsfiddle, too:
https://jsfiddle.net/7dvar8nx/1/
So this is a complex duplicate of bug 972595, ultimately, I think. :)
Comment 8•10 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #7)
> Indeed, this was the problem in the initial jsfiddle, too:
> https://jsfiddle.net/7dvar8nx/1/
(^ is the "fixed" version of the jsfiddle from comment 0, to use flex-basis of "auto" & width:10px, instead of flex-basis:10px. That's the workaround I'd suggest for this at the moment.)
> So this is a complex duplicate of bug 972595, ultimately, I think. :)
Er, sorry, that might've been the wrong bug number...
Comment 9•10 years ago
|
||
(Nope, that was the right bug number; though that bug was about spec text that has since been rewritten, so I've now duped bug 972595 forward to bug 1055887.)
So: this ultimately depends on bug 1055887, which is about implementing the up-to-date spec-language on intrinsic sizing of flex containers, based (in part) on their item's flex base sizes. (Currently we base it on their items' preferred width values (which ends up depending on the item's content in this case, via "width:auto")).
Leaving this as its own bug for now, so we can circle back to this when bug 1055887 is fixed.
Reporter | ||
Comment 10•10 years ago
|
||
I understand there are workarounds for specific use cases. Using width though breaks how the flex container should function when inner flex-items are changed.
https://jsfiddle.net/eeo76ca3/5/
I changed .innerFlex from flex: 1 1 0px; min-width: 0; to flex: 1 1 auto; Since in .midFlex you used width directly it's set to a fixed number. If it we change .midFlex back to the old case you'd see the correct behavior: https://jsfiddle.net/eeo76ca3/6/ (The red box is around all of "Hellooooo" because .midFlex's min-width is auto overriding the flex-basis).
In theory according to the spec it should be possible to build a whole flex layout without ever using width and height. I'm trying to get every browser to that level of support.
Comment 11•10 years ago
|
||
(In reply to warcraftthreeft from comment #10)
> I understand there are workarounds for specific use cases. Using width
> though breaks how the flex container should function when inner flex-items
> are changed.
Ah, right -- unlike "flex-basis", an explicit "width" can reduce the resoled value of "min-width:auto". So, pushing the flex-basis value into "width" isn't a perfect workaround, if you're relying on min-width:auto. (I think that's what you're saying here.)
> In theory according to the spec it should be possible to build a whole flex
> layout without ever using width and height. I'm trying to get every browser
> to that level of support.
Right. FWIW, I'm picking out my high-priority bugs for the immediate future right now, and I think bug 1055887 (which should address this issue) is among them.
Updated•10 years ago
|
Summary: Flex-basis not respected by nested flex items → Flex-basis not respected when intrinsically sizing nested flex items
Updated•3 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•