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

On Mon, Jul 22, 2013 at 10:54 AM, fantasai
<fantasai.lists@inkedblade.net> wrote:
> On 07/19/2013 12:14 PM, Tab Atkins Jr. wrote:
>> 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.
>
> Nobody is proposing to change 'visibility'.

Sorry, fat fingers.  I meant 'overflow' there.

> And the fix for cases
> that need to be tweaked will be to adjust the min-size, which is
> fairly well related to the behavior that needs adjusting (not
> shrinking enough).

Well, no.  Sometimes the right fix is to tweak 'overflow'.  And
regardless, tweaking 'min-*' isn't obvious at all, because you never
have to do that for anything else, ever, in all of CSS.  'min-*' is a
completely opt-in feature everywhere else.  This would change it to
something you have to actively *turn off* sometimes.

Fundamentally, I suspect this will end up as the same problem that Old
Flexbox had, where you had to set *two* properties (box-flex and
width) in order to get the commonly-desired absolute-flexing behavior,
and the required value for 'width' was extremely non-obvious (you
never set anything to width:0 unless you're actively trying to hide
it).

We know from lots of complaints that this was persistently confusing
to authors, even advanced ones.  I don't want to reintroduce the same
issue, but worse (because the required second property is min-*, which
is much less common).

>> 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.
>
> You mean, setting flex-shrink to 0 on <img>, <object>, etc. in the
> UA style sheet?

No, what I mean is exactly what I said in the paragraph immediately
before your quote here, which you trimmed for some reason.  Have
'flex-shrink' take an "auto" value as its initial value, which is
resolved at used-value time to either 0 or 1 based on whether the item
is a replaced element or not.  This fixes the image issue handily
(while avoiding the question of whether something is a replaced
element at computed-value time), without affecting anything else,
where auto-shrinking is generally a good idea.

>>>    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).
>
> I think you're way mixed up here... min-content's definition is correct.
> We're just not being careful about how we're using it in Flexbox. Think
> about it a bit more. :)

I'm not so sure about this.  The contents of a normal element have an
intrinsic size, and so min-content has a natural and reasonable
definition - it's the smallest size you can be without overflowing.
Replaced elements have no contents, though, and their intrinsic size
is merely the size they prefer to be at if there are no stronger
constraints on them.  We've reused this intrinsic size as their
min-content size, but it's not true - you can totally shrink them
below that size without overflowing!

Saying that we should just be careful to treat min-content as not the
actual minimum size of some elements seems to be a cop-out.  It might
be a necessary one, but I'm not certain that's been well-established,
and this shouldnt' just be swept under the rug.

>>> 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.
>
> Can you give specific examples? Because last time we discussed this,
> you gave exactly such a handwavy explanation, saying there were problems
> in the CR (but not giving any specific examples), and asserted that your
> proposed fix would have no problematic implications. And then Elliott
> posted some. So, I don't feel inclined to trust your handwavy explanations.
> Show me the code.

Okay, so here's some markup demonstrating the problem in a simple way:

~~~~
<!DOCTYPE html>
<column id=top>
  <row>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
  </row>
  <row>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
  </row>
  <row>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
    <column><x></x><x></x><x></x></column>
  </row>
</column>
<style>
body * {
padding: 5px;
margin: 5px;
background: rgba(0,0,0,.2);
}
row, column {display: -webkit-flex;}
column {-webkit-flex-flow: column;}
row {-webkit-flex-flow: row;}
x { height: 100px; min-height: 100px; }
column { min-height: 360px;}
row {min-height: 380px; }
#top { min-height: 1200px; }
~~~~

I've manually added min-heights to the elements to simulate
min-height:min-content, since that doesn't actually work yet.

So, it's really big.  To be expected, since it's full of large things.

Now, imagine you want #top to fill a smaller container, and just
scroll to the overflowing parts.  You add this to your stylesheet:

    #top { height: 600px; overflow: auto; }

...but nothing happens.  The implicit min-content height keeps it at
1200px high no matter what you do, unless you realize that you needed
to add a min-height:0 to manually override it.  Based on my experience
with authors asking me for help, authors don't run into this; instead,
they try and shrink items further down the hierarchy, as that's an
obvious candidate for "it's too big!".  Even if they override the
min-height on one of the inner elements, though, the outer elements
are still enormous, because *the min-content height of an element
doesn't pay attention to the actual height*.  That is, changing the
'min-height' and the 'height' of an element to make it smaller *has no
effect on what the parent flexbox sees* - the parent flexbox will
still make itself big, based on the min-content size, except that now
it's super-confusing because it's not even fully filled!  You've
shrunk the big elements, but your outer flexboxes are still enormous,
and you just can't figure out why.

This is not a hypothetical situation.  It's happened to several of my
fellow engineers attempting to use Chrome's flexbox impl back when we
had the min-content behavior.  This appears to be a pretty basic and
easy-to-hit failure mode that's hard to dig yourself out of.

On the other hand, with the current spec, you get what you asked for -
the content shrinks to 600px high.  It'll attempt to shrink all the
contents accordingly to fit without overflowing, too - if you don't
like that, it'll fail in an obvious way,  where the too-large item
overflows.  It's not difficult to find the offending element and
figure out how to fix it, by stopping it from shrinking, setting an
explicit min-height (you can use min-content in the future, when
implementations support it for height), or setting 'overflow' on it to
get scrollbars.

Like I said, this is just an elaboration on your case #4, but more
confusing/difficult to debug.

~TJ

Received on Thursday, 25 July 2013 19:47:47 UTC