Re: [css-flexbox] min-width/height: min-content defaults for replaced items and overflow containers

On Thu, Jul 18, 2013 at 6:28 PM, fantasai <fantasai.lists@inkedblade.net> wrote:
> On 04/22/2013 04:50 PM, Elliott Sprehn wrote:
>>
>> Recently the spec for flexbox was changed so that the min-width
>> of flex items was no longer min-content (mutatis mutandis for
>> height), but this produces some bad behavior when using replaced
>> things like <button> or <img> as flex items. Previously they
>> had an implicit min-width: min-content which would prevent them
>> from becoming smaller, but now they'll end up being crushed.
>>
>> ex.
>>
>> <div style="display: flex;">
>>    <img width="200" height="200">
>>    <p>some long text that should wrap here</p>
>> </div>
>>
>> In this example the <img> can end up being considerably less
>> than 200px wide which isn't what the author intended.
>>
>> Before this change was made to the spec the min-width was
>> min-content which worked fine for this but had other bad behavior
>> like making overflow: scroll on a flex item behave unexpectedly
>> since the item would expand out to the min-content size. [...]
>>
>>
>> Both of these have proven to be surprising behavior, instead I
>> think we should combine the behavior so the min-width is
>> min-content unless your overflow property computes to a value
>> other than visible in which case it should be 0.
>>
>> This special cased behavior gives a sensible result for <img>
>> and overflow: scroll as flex items.
>
>
> Overview
> --------
>
> So, this issue has been making me very uneasy about the resolution
> we took in March about dropping 'min-width: auto', and I've concluded
> that I would really like us to re-examine it.
>
> I believe flexbox should generally "just work", and not do surprising
> weird things. Clearly there were problems with the original definition
> of 'auto', because it did weird things. But not having 'auto' also
> does weird things. Imho the right thing to do is fix 'auto' instead
> of dropping it.
>
> Concerns
> --------
>
> These are the concerns on my mind:
>
>   - Flexbox allows shrinking by default. It should honor intrinsic
>     sizes such that things that have a definite size in the author's
>     mind don't get squashed unexpectedly. (For example, Elliott's case
>     should Just Work. At the very least, it should Make Sense, which
>     it doesn't, really, in the ED.)

Ultimately, this issue comes down to deciding *which* cases should
Just Work.  It's impossible to make them all work, and so it's
misleading to look at individual cases and figure out their optimal
behavior, because that ignores the effects that a change will have on
other cases.

>   - Relatedly, overflowing the flexbox with flex items is better
>     than having the contents of flex items overflow into each other
>     in order to make the flex items fit inside the flex container.
>
>   - However, the contents of scrolly things should not be considered
>     when sizing a flex item, because for scrolly things we don't
>     really care how long the stuff is inside; that's the point of
>     making it scrolly. This was Ojan's problem with the CR.
>
>   - Don't confuse people by imposing the intrinsic size of something
>     as its min-size when it's been explicitly sized to be smaller.
>     This is also a problem with the CR.
>
> Proposal
> --------
>
> Mostly as Elliott and Alexmog stated, but slightly different --
> Reinstate 'auto', but change its definition to
>
>   if (overflow != visible):
>     min-width/height = 0;
>   else
>     min-width/height = min(min-content, width/height);
>
> This makes 'auto' a little more magic than 'min-content', but gives
> expected results more cases. If someone wants something else special,
> they can ask for it by setting the min-size or flex-basis explicitly.
>
> The only sensible cases that if-clause fails are:
>   * wanting a min-content min-size when 'overflow' is 'hidden'
>   * wanting a min-size smaller than min(min-content, size)
>     when 'overflow' is 'visible'

This level of additional complication, where the meaning of a
'min-width' keyword depends on 'overflow', was something we were
uncomfortable with.  I prefer something that imposes slightly more
work on authors in some cases in return for simpler-to-understand
behavior overall, so that when the defaults fail, it's easier to
figure out how to fix it through simple fiddling.  Changing
'visibility' is *not* something that someone will think of unless they
are actively reading the spec.

>   Case #2:
>
>     Elliott's case.
>
>
>       <div style="display: flex;">
>         <img width="200" height="200">
>         <p>some long text that should wrap here [... like a paragraph ...]
> </p>
>       </div>
>
>       +--------+
>       | Image  |
> +---------------------------------------...------------------...--+
>       |        |  +  | some long text that should wrap here [... like a
> paragraph ...] |
>       |        |
> +---------------------------------------...------------------...--+
>       +--------+
>
>     Suppose the ratio of the image width to the text length is 1:19.
>     In the current ED, if we put the image and the paragraph into a
>     flexbox of size 500, the image will squash down to 25px by default.
>
>
>        ++-------------------+        +--------+------------+
>        ||... text ..........|   vs   | Image  |... text ...|
>        ||.................. |        |        |........... |
>        ++-------------------+        |        |............|
>                                      +--------+------------+
>
>     This is somewhat surprising given that images don't grow by default,
>     and in an authors mind, are a kind of fixed-size element with respect
>     to text-filled boxes and such things.

Yes, this is the basic failure case for the ED behavior.  It's the
thing we had to trade off in order to get better behavior elsewhere.

Hmm.  Maybe we can fix this directly, without breaking other cases.
Perhaps flex-shrink could take an "auto" value (which is also the
initial value), and it computes to 0 for replaced elements (or just
anything with an intrinsic size) and 1 for everything else?  Ugh, we
can't have it compute, due to the image/alt case - it'll have to stick
around until the layout algorithm, and be taken into account there.

Given that the fix for this case in current WK/B/FF code is to
manually set flex-shrink to 0, that shouldn't break existing pages
much at all.

This would give us all the benefits of the ED behavior, while fixing
its biggest failure mode, and without screwing with any other cases.

>   Case #3:
>
>     Hidden in Elliott's case is the distinction between intrinsic size
>     and declared size. Suppose the image's intrinsic width is not 200px,
>     but 400px, but the author declared its 'width' property as '200px'.
>
>     If we use its min-content size as a minimum, its size floors at
>     400px, not 200px, which is probably quite surprising to the author.
>     Which is why the automatic minimum, if any, should not be greater
>     than the specified size. This is a problem with the current CR.

This might be an issue with the definition of min-content itself, to
be honest.  For "scalable" elements, the min-content width/height
shouldn't be larger than the specified size (perhaps only if the
specified size is a definite length).

>   Case #4:
>
>     Ojan's case.
>
>
>       <div style="display: flex; height: 100%;">
>         <div style="overflow: scroll;">
>            ... thousand 100px tall items ...
>         </div>
>       </div>
>
>     In the CR version of the spec...
>
>     > The overflow: scroll <div> would end up being as tall as it's
>     > min-content size which is the height of all the items and you
>     > wouldn't get a scrollbar. Instead you needed to use min-height: 0
>     > on the <div> to get your scrollbar to work [which has] proven
>     > to be surprising behavior

>   Case #6:
>
>     A column flex item with user-generated flow content, including
>     a large image.
>
>     * If min-width: min-content is implied (Flexbox CR), too much
>       content will cause flex items to overflow the flex container.
>
>     * If min-width: min-content is not implied (Flexbox ED), too much
>       content will overflow the flex item. This is generally worse.
>       See Case #1 above.
>
> I tried to extract cases from the original thread on this topic, but
> there were no specific examples, just generalized complaints. :(
>   http://lists.w3.org/Archives/Public/www-style/2013Feb/0364.html

This is just case #4, except that some of the complaints were even
stronger, about nested flexboxes (particularly when they have
different flex-direction values). Making the entire flexbox huge is
confusing and frightening, and hard to debug.  Having the items
overflow the flexbox looks similar if you just stare at the results,
but is *much* easier to debug, because dev tools correctly show the
sizes/bounds of items so you can tell that it's an overflow problem.
You then smack your forehead and curse that "overflow:visible" is the
default, as usual.

So no, the ED behavior is *not* generally worse.  It's *way* better to
debug, and that's the important point.

> Compatibility
> -------------
>
> MSIE10 implements an implied min-content minimum whenever min-size is zero,
> so applications built on their flexbox implementation would already rely
> on a min-content minimum. The cases that would experience a change are:
>   * specified size < intrinsic size
>       This is unlikely to cause a problem, more likely to fix one.
>   * relying on min-content minimum while overflow != visible
>       This is unlikely except in the case of 'overflow: hidden'.
>
> Summary: Content built for IE10 Flexbox would need to change only if
>          it relies on the min-content minimum taking effect on flex
>          items with 'overflow: hidden'.
>
> WebKit and Mozilla currently implement a zero minimum, so applications
> built on their flexbox implementation might rely on the ability to
> shrink below the min-content size. Since we are only changing behavior
> where overflow is visible, the cases that would experience a change are:
>   * relying on content's ability to visibly overflow the flex item
>     without affecting its size.
>       Pages generally aren't designed to use visible overflow, so
>       this is mainly a change in "error" handling. It will result
>       in better error-handling in some cases (Case #1, #6) and worse
>       in others (Case #5).
>
> Summary: Content built for Webkit/Mozilla Flexbox would need to change
>          only if it relies on content visibly overflowing a flex item
>          (and not stretching it).

Content does rely on that when setting up complex pages with nested
flexboxes, for debuggability.  I'm strongly against changing this,
though I'm okay with pursuing a fix for Case #2 (the major failure
mode for the current ED behavior), as I outline above.

~TJ

Received on Friday, 19 July 2013 19:15:09 UTC