[css-flexbox] "flex: 1;" does the wrong thing in min-size constraint sizing

Short summary: Flexbox is hard, y'all.

Load up the following code in tip-of-tree webkit or blink:

<!doctype html>
<div id=parent>
  <div id=child>foo</div>
</div>
<style>
#parent {
  display: -webkit-flex;
  -webkit-flex-flow: column;
  border: 1px solid;
}
#child {
  -webkit-flex: 1;
}
</style>

(If you're not on tip-of-tree, you can get the desired effect by
setting "min-width: 0;" on the child - this is now the default again
on ToT.)

The behavior here is that the #parent tries to shrinkwrap its height,
which is computed from the flex-basis of its children.  However,
"flex: 1;" sets the flex-basis to 0 (a behavior we wanted from the
beginning, due to persistent author confusion about why their elements
that were all "flex: 1;" weren't the same size).  Thus, the shrinkwrap
height of the #parent is now 0, and the #child overflows.

Per <https://code.google.com/p/chromium/issues/detail?id=240741> and
<https://bugs.webkit.org/show_bug.cgi?id=116107>, this has already
broken united.com, and by implication, probably a bunch of other
Sharepoint sites.

The underlying issue is that you're saying you want the element to
flex, and we get out of your way and believe you.  But then the
element is *unable* to flex, because it's being sized under a min-size
constraint.  This will likely be a common authoring error (after all,
we already have existence proof of it happening).  It will also happen
if you float the flexbox, or anything else that shrinkwraps the width,
but right now WebKit/Blink are buggy and ignore the flex-basis when
doing width shrinkwrapping.

Proposed solution: we add a new value, provisionally named
"dont-shrink-me-bro" until someone comes up with something better.
This value sticks around until used-value time, eventually being
treated as 'min-content' if the element is sized under a min-size
constraint, or 0 otherwise.  This becomes the new value for
'flex-basis' when it's omitted from the shorthand, so "flex: 1;"
expands to "flex: 1 1 dont-shrink-me-bro;".

This seems to handle the problem with a minimum of magic, and might be
useful outside of flexbox.

(I had thought we might be able to solve this by adopting fantasai's
suggestion of hooking min-width/height resolution to 'overflow', but
it doesn't work - this problem is just as bad if #child has a
scrollbar.)

~TJ

Received on Tuesday, 14 May 2013 18:13:31 UTC