- From: fantasai <fantasai.lists@inkedblade.net>
- Date: Thu, 18 Jul 2013 16:28:35 -0700
- To: Elliott Sprehn <esprehn@gmail.com>
- CC: www-style list <www-style@w3.org>, Daniel Holbert <dholbert@mozilla.com>, Alex Mogilevsky <alexmog@microsoft.com>, Rossen Atanassov <Rossen.Atanassov@microsoft.com>
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.) - 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' Use Cases --------- Case #1: This was an original motivation for the min-size constraint. It protects against multiple overlapping flex item overflows when the flexbox is smaller than the author expected. (This would be a reasonably common and unnoticeable mistake, because authors generally don't check on small screen sizes.) <ul class="nav"> <li>... <li>... ... </ul> As either a row or column flexbox, the CR version creates a stack of items that overflows the flex container: +=======================+ |[ Item 1 ] [ Item 2 ] [ Item 3 ] [ Item 4 ] +=======================+ Whereas the ED fits all flex items into the container, but causes their content to individually overflow the items and overlap: +========================+ |[ It]m[1It]e[mI#]e[mI#] | +========================+ Remember, the same problem applies to a vertical flexbox, even if you put a scrollbar on it. +------------+ +------------+ | [ Item 1 ] | vs. | ⁅#########⁆| /* I can't ASCII-draw half-overlapped text. :( */ | [ Item 2 ] | | ⁅#########⁆| /* Use your imagination. */ +-[ Item 3 ]-+ +------------+ [ Item 4 ] 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. 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. 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 #5: A row flex item with user-generated flow content, including a large image. +---------+---------------------------------------+ | sidebar | main content | +---------+---------------------------------------+ * If min-width: min-content is implied (Flexbox CR), this could make the flex item too wide if the image is really wide, similar to how table-based layouts get messed up by such situations. This is, at least, a familiar problem and can show up on reasonably-sized screens if present, so will hopefully be noticed and handled by he author. <----------------- page size ---------------------> +---------+-----------------------------------------------------+ | sidebar | main content wraps to this wide.....................| | | ...... | | | [############### really wide image ################]| +---------+-----------------------------------------------------+ * If min-width: zero is implied (Flexbox ED), wide content will overflow the flex item, either drawing under the next flex item (see Case #1) or drawing off the right edge of the page. <----------------- page size ---------------------> +---------+---------------------------------------+ | sidebar | main content wraps to this wide.......| | | .................... | | | [############### really wide image ################] +---------+---------------------------------------+ In both behaviors, if the item contains significant flow content, an explicit min-width is recommended. For the CR version, to override the min-content behavior, and for the ED version, to provide a reasonable minimum. (Otherwise, as the flex container narrows to zero, content wrapping approaches dysfunctional, breaking at every opportunity.) http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#min-size-auto 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 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). Thanks for your consideration~ Congrats if you read through to the end! ;) ~fantasai
Received on Thursday, 18 July 2013 23:29:04 UTC