[css-flexbox] min-height on flex items that have an intrinsic aspect ratio

# Greg Whitworth (2 years ago)

Hello,

We came across an interesting issue regarding the min-height of a flex item[1] when the flex item has an intrinsic aspect ratio. We are setting the flex base size according to the aspect ratio but the hypothetical main size ignores it by applying the min size property. Because of this, I suggest rewording section 4.5 from:

On a flex item whose overflow is visible

to this:

On a flex item whose overflow is visible and does not have an intrinsic aspect ratio.

I have created a repro of the issue that you can see in IE11 currently[3] as well as a repro for Chrome that makes it support 4.5 and shows the same result[4] as IE. Any feedback would be greatly appreciated. Thanks.

Greg

[1] dev.w3.org/csswg/css-flexbox/#min-size-auto [2] dev.w3.org/csswg/css-flexbox/#algo-main-item [3] jsfiddle.net/kdcwu/6 [4] jsfiddle.net/kdcwu/9

Contact us to advertise here
# Tab Atkins Jr. (2 years ago)

On Sat, May 17, 2014 at 2:55 AM, Greg Whitworth gwhit@microsoft.com wrote:

Hello,

We came across an interesting issue regarding the min-height of a flex item[1] when the flex item has an intrinsic aspect ratio. We are setting the flex base size according to the aspect ratio but the hypothetical main size ignores it by applying the min size property. Because of this, I suggest rewording section 4.5 from:

On a flex item whose overflow is visible

to this:

On a flex item whose overflow is visible and does not have an intrinsic aspect ratio.

That's definitely not the fix that we want, because one of the main drivers for the "min-width: auto;" behavior was items with intrinsic aspect ratios (preventing <img>s from shrinking), but your issue is

valid.

The problem is that the Sizing spec doesn't handle elements with aspect ratios well when talking about min-content size. That's the part that needs to be fixed to have this work properly, both in Flexbox and everywhere else that talks about the min-content size of an element. For example, in a shrink-wrapped table cell, if the height of the image is specified as half its intrinsic height, its width contribution to the table should likewise be half its intrinsic width.

~TJ and fantasai

# fantasai (2 years ago)

On 05/19/2014 07:21 AM, Tab Atkins Jr. wrote:

For example, in a shrink-wrapped table cell, if the height of the image is specified as half its intrinsic height, its width contribution to the table should likewise be half its intrinsic width.

Sorry, I gave a bad example here. A more accurate example would be a 100x100 image with a specified width of 50px and a specified height of 'min-content': the resulting height should be 50px, similar to how a paragraph's height is (in a more sophisticated relationship) the result of applying its intrinsic constraints to a specified width.

~fantasai

# Greg Whitworth (2 years ago)

On 05/19/2014 07:21 AM, Tab Atkins Jr. wrote:

For example, in a shrink-wrapped table cell, if the height of the image is specified as half its intrinsic height, its width contribution to the table should likewise be half its intrinsic width.

Sorry, I gave a bad example here. A more accurate example would be a 100x100 image with a specified width of 50px and a specified height of 'min- content': the resulting height should be 50px, similar to how a paragraph's height is (in a more sophisticated relationship) the result of applying its intrinsic constraints to a specified width.

Thanks for the feedback but I don't think that that solves the problem in this particular case because the width provided was not definite. What should happen to that same 100x100 image if the width is set to 100% with a height of 'min-content'? Your example is currently how IE behaves, if you take the fiddle example[1] from before and apply a definite width its aspect ratio is maintained due to the fact that 4.5 gives us that out and we uphold section 9.2.3B.

Greg

[1] jsfiddle.net/kdcwu/6/ [2] jsfiddle.net/kdcwu/10/ [3] jsfiddle.net/kdcwu/11 (webkit version)

# Tab Atkins Jr. (2 years ago)

On Mon, May 19, 2014 at 1:26 PM, Greg Whitworth gwhit@microsoft.com wrote:

On 05/19/2014 07:21 AM, Tab Atkins Jr. wrote:

For example, in a shrink-wrapped table cell, if the height of the image is specified as half its intrinsic height, its width contribution to the table should likewise be half its intrinsic width.

Sorry, I gave a bad example here. A more accurate example would be a 100x100 image with a specified width of 50px and a specified height of 'min- content': the resulting height should be 50px, similar to how a paragraph's height is (in a more sophisticated relationship) the result of applying its intrinsic constraints to a specified width.

Thanks for the feedback but I don't think that that solves the problem in this particular case because the width provided was not definite. What should happen to that same 100x100 image if the width is set to 100% with a height of 'min-content'? Your example is currently how IE behaves, if you take the fiddle example[1] from before and apply a definite width its aspect ratio is maintained due to the fact that 4.5 gives us that out and we uphold section 9.2.3B.

Circling back here, we think we fixed this back in May, by adding the following lines to the "min-width/height: auto" requirements:

<li>if the item has no intrinsic aspect ratio, its <a>min-content size</a>,

<li>if the item has an intrinsic aspect ratio,

the width (height) calculated from

the aspect ratio and any definite size constraints in the opposite dimension

Does this work? We think it does.

~TJ

# fantasai (2 years ago)

On 07/01/2014 10:34 AM, Tab Atkins Jr. wrote:

On Mon, May 19, 2014 at 1:26 PM, Greg Whitworth gwhit@microsoft.com wrote:

On 05/19/2014 07:21 AM, Tab Atkins Jr. wrote:

For example, in a shrink-wrapped table cell, if the height of the image is specified as half its intrinsic height, its width contribution to the table should likewise be half its intrinsic width.

Sorry, I gave a bad example here. A more accurate example would be a 100x100 image with a specified width of 50px and a specified height of 'min- content': the resulting height should be 50px, similar to how a paragraph's height is (in a more sophisticated relationship) the result of applying its intrinsic constraints to a specified width.

Thanks for the feedback but I don't think that that solves the problem in this particular case because the width provided was not definite. What should happen to that same 100x100 image if the width is set to 100% with a height of 'min-content'? Your example is currently how IE behaves, if you take the fiddle example[1] from before and apply a definite width its aspect ratio is maintained due to the fact that 4.5 gives us that out and we uphold section 9.2.3B.

Circling back here, we think we fixed this back in May, by adding the following lines to the "min-width/height: auto" requirements:

<li>if the item has no intrinsic aspect ratio, its <a>min-content size</a>,

<li>if the item has an intrinsic aspect ratio,

the width (height) calculated from

the aspect ratio and any definite size constraints in the opposite dimension

Does this work? We think it does.

We've gone ahead and expanded this out to be more comprehensive. The new text is at dev.w3.org/csswg/css-flexbox/#min-size-auto

(Note, we also incorporated handling of 'width' and 'height' to avoid surprises when the author specifies a size smaller than the min-content size.)

~fantasai

# Daniel Holbert (a year ago)

On 08/19/2014 01:43 PM, fantasai wrote:

Circling back here, we think we fixed this back in May, by adding the following lines to the "min-width/height: auto" requirements:

<li>if the item has no intrinsic aspect ratio, its <a>min-content

size</a>,

<li>if the item has an intrinsic aspect ratio,

the width (height) calculated from

the aspect ratio and any definite size constraints in the opposite

dimension

Does this work? We think it does.

We've gone ahead and expanded this out to be more comprehensive. The new text is at dev.w3.org/csswg/css-flexbox/#min-size-auto

(Note, we also incorporated handling of 'width' and 'height' to avoid surprises when the author specifies a size smaller than the min-content size.)

Hi fantasai/tab/Greg,

I've just realized that the "expanding"/"more comprehensive" rewrite in August 2014 here actually changed behavior in a pretty substantial way.

The changeset hinted at in this ^ message that I'm replying to was: hg.csswg.org/drafts/rev/9b745a07d529

Importantly:

  • Before this commit, it was clear that min-content size is ignored when resolving "min-width:auto", for flex items that have an intrinsic aspect ratio.
  • But after this commit, min-content size is needed & used when resolving "min-width:auto" for these flex items. (It's just clamped by transferred min/max properties in the other direction, and if there happens to also be a definite cross-size property, that can push the min-size lower.)

So in a case with e.g. an <img> with min-width:auto & no cross-size properties, the spec now requires that we now clamp it to its min-content main size, when it previously did not.

Example: jsfiddle.net/410jorp8/1 (partially stolen from a codepen in a different thread here) The min-content width of the image there is 300px. But Firefox allows it to be smaller than that (using its flex-basis of "50px", & not clamping to the min-content size). This is correct per the pre-August spec-language, but it's incorrect per the current spec language.

I prefer the pre-August behavior on this point, because min-content sizes aren't really a useful lower-bound for flex items with aspect ratios. These flex items can shrink (honoring their intrinsic aspect ratio) below their min-content size, without overflowing.

Was this behavior-change intentional? (making min-width:auto depend on min-content size, for items w/ intrinsic aspect ratios)

Thanks, ~

# Philip Walton (a year ago)

On Tue, Feb 24, 2015 at 11:16 AM, Daniel Holbert dholbert@mozilla.com

wrote: >

I prefer the pre-August behavior on this point, because min-content sizes aren't really a useful lower-bound for flex items with aspect ratios. These flex items can shrink (honoring their intrinsic aspect ratio) below their min-content size, without overflowing.

This makes a lot of sense to me, and I think the example is quite compelling. Given an <img> flex item whose only CSS declaration is `flex: 0

0 50px`, it seems quite strange (and unexpected) to have its rendered size be 300px wide/tall.

# Daniel Holbert (a year ago)

On 02/24/2015 11:16 AM, Daniel Holbert wrote:

Hi fantasai/tab/Greg,

I've just realized that the "expanding"/"more comprehensive" rewrite in August 2014 here actually changed behavior in a pretty substantial way. [...] Importantly:

  • Before this commit, it was clear that min-content size is ignored when resolving "min-width:auto", for flex items that have an intrinsic aspect ratio.
  • But after this commit, min-content size is needed & used when resolving "min-width:auto" for these flex items. (It's just clamped by transferred min/max properties in the other direction, and if there happens to also be a definite cross-size property, that can push the min-size lower.)

Was this behavior-change intentional? (making min-width:auto depend on min-content size, for items w/ intrinsic aspect ratios)

Following up here -- as noted elsewhere[1], I discussed this issue with Tab/fantasai/Greg/Rossen today, and confirmed that the spec behavior-change here was intentional.

There was a problem with the previous behavior (allowing images to shrink to 0 by default). If you had 2 unstyled flex items -- an <img> and a paragraph of text -- then the paragraph will have a large hypothetical size (the length of its text laid out on a single line), so we'll be forced to shrink both items. And if the <img> can shrink below its intrinsic size by default, then it'll do so in this scenario, and that's unintuitive. The amount that it shrinks is also a bit arbitrary, too -- it depends on how much we overflow, which depends on how much text we've got in the other flex item.)

So, images won't shrink below their intrinsic sizes by default (but this can be overridden in various ways as described in the spec).

So, we need to adjust Firefox to match the updated spec-text. Here's my Firefox bug on this for reference: bugzilla.mozilla.org/show_bug.cgi?id=1136312

~Daniel

[1] lists.w3.org/Archives/Public/www-style/2015Mar/0024.html (This issue is labeled "(3)" in that post.)

# Tab Atkins Jr. (a year ago)

On Wed, Feb 25, 2015 at 7:13 PM, Philip Walton philip@philipwalton.com wrote:

On Tue, Feb 24, 2015 at 11:16 AM, Daniel Holbert dholbert@mozilla.com wrote:

I prefer the pre-August behavior on this point, because min-content sizes aren't really a useful lower-bound for flex items with aspect ratios. These flex items can shrink (honoring their intrinsic aspect ratio) below their min-content size, without overflowing.

This makes a lot of sense to me, and I think the example is quite compelling. Given an <img> flex item whose only CSS declaration is flex: 0 0 50px, it seems quite strange (and unexpected) to have its rendered size be 300px wide/tall.

That doesn't happen. The rules for min-width:auto specifically take into account if the item has a definite flex-basis (or it has flex-basis:content and a definite width).

As far as we can tell, the current spec gives the best of all worlds here - if you don't specify anything special, images won't shrink below their intrinsic size, but if you do specify an explicit size, they're allowed to shrink down to that.

~TJ

# Daniel Holbert (a year ago)

On 03/02/2015 04:16 PM, Tab Atkins Jr. wrote:

On Wed, Feb 25, 2015 at 7:13 PM, Philip Walton philip@philipwalton.com wrote:

On Tue, Feb 24, 2015 at 11:16 AM, Daniel Holbert dholbert@mozilla.com wrote:

I prefer the pre-August behavior on this point, because min-content sizes aren't really a useful lower-bound for flex items with aspect ratios. These flex items can shrink (honoring their intrinsic aspect ratio) below their min-content size, without overflowing.

This makes a lot of sense to me, and I think the example is quite compelling. Given an <img> flex item whose only CSS declaration is flex: 0 0 50px, it seems quite strange (and unexpected) to have its rendered size be 300px wide/tall.

That doesn't happen. The rules for min-width:auto specifically take into account if the item has a definite flex-basis (or it has flex-basis:content and a definite width).

Tab -- I think you're mistaken on this.

A definite flex basis (50px in this case) does not influence "min-width:auto". At least, I don't see anything about that in the spec.

(note: if it were considered, then "flex: 1" (i.e. flex: 1 0 0%) would lose its magic min-size-clamping behavior, which would be bad.)

So I think what Philip said is correct -- this image would indeed end up at 300px (despite flex: 0 0 50px).

(We might just need to solve this with web-author education/outreach... The unexpected result makes more sense if you keep in mind that flex-basis is just the starting-point for flexing, and that min/max-size properties reign supreme, and that min-size defaults to intrinsic width.)

~

# Tab Atkins Jr. (a year ago)

On Mon, Mar 2, 2015 at 5:16 PM, Daniel Holbert dholbert@mozilla.com wrote:

On 03/02/2015 04:16 PM, Tab Atkins Jr. wrote:

On Wed, Feb 25, 2015 at 7:13 PM, Philip Walton philip@philipwalton.com wrote:

On Tue, Feb 24, 2015 at 11:16 AM, Daniel Holbert dholbert@mozilla.com wrote:

I prefer the pre-August behavior on this point, because min-content sizes aren't really a useful lower-bound for flex items with aspect ratios. These flex items can shrink (honoring their intrinsic aspect ratio) below their min-content size, without overflowing.

This makes a lot of sense to me, and I think the example is quite compelling. Given an <img> flex item whose only CSS declaration is flex: 0 0 50px, it seems quite strange (and unexpected) to have its rendered size be 300px wide/tall.

That doesn't happen. The rules for min-width:auto specifically take into account if the item has a definite flex-basis (or it has flex-basis:content and a definite width).

Tab -- I think you're mistaken on this.

A definite flex basis (50px in this case) does not influence "min-width:auto". At least, I don't see anything about that in the spec.

(note: if it were considered, then "flex: 1" (i.e. flex: 1 0 0%) would lose its magic min-size-clamping behavior, which would be bad.)

So I think what Philip said is correct -- this image would indeed end up at 300px (despite flex: 0 0 50px).

(We might just need to solve this with web-author education/outreach... The unexpected result makes more sense if you keep in mind that flex-basis is just the starting-point for flexing, and that min/max-size properties reign supreme, and that min-size defaults to intrinsic width.)

I literally checked in the fix for that yesterday, it's not showing up in the spec for some reason. I'll check this out.

(Right now the spec only pays attention if 'width' is definite and "flex-basis:auto". I'm 95% certain this was an oversight, and having a definite 'flex-basis' should have the same effect. My commit that's not showing up added that, and fixed the other condition to talk about "flex-basis:content" instead.)

~TJ

# Daniel Holbert (a year ago)

On 03/03/2015 09:25 AM, Tab Atkins Jr. wrote:

I literally checked in the fix for that yesterday, it's not showing up in the spec for some reason. I'll check this out.

Looks like it made it in now. ("If the item’s computed flex-basis is definite"...)

I don't agree with this change, though.

(Right now the spec only pays attention if 'width' is definite and "flex-basis:auto". I'm 95% certain this was an oversight, and having a definite 'flex-basis' should have the same effect.

I don't think it was an oversight -- the distinction is important.

With your change (allowing definite values in "flex-basis" to influence resolved min-width:auto), this will allow shrinkage below the min-content width (and cause overflow) when authors specify e.g. "flex: 1", which would make "flex: 1" much more dangerous to use.

As I recall, the whole idea of shorthands like "flex: 1" is that you can make your items grow equally from 0, with a guarantee that each item will be large enough to not have content overflowing. This change breaks that, and would likely cause backwards-compatibility headaches as a result.

# Daniel Holbert (a year ago)

On 03/03/2015 10:13 AM, Daniel Holbert wrote:

With your change (allowing definite values in "flex-basis" to influence resolved min-width:auto), this will allow shrinkage below the min-content width (and cause overflow) when authors specify e.g. "flex: 1", which would make "flex: 1" much more dangerous to use.

(er, pedantic self-nit: "shrinkage" was the wrong term to use there, since in this example we'd be flexing from 0. "insufficient growth" is really what I meant to say.)

# Tab Atkins Jr. (a year ago)

On Tue, Mar 3, 2015 at 10:13 AM, Daniel Holbert dholbert@mozilla.com wrote:

On 03/03/2015 09:25 AM, Tab Atkins Jr. wrote:

I literally checked in the fix for that yesterday, it's not showing up in the spec for some reason. I'll check this out.

Looks like it made it in now. ("If the item’s computed flex-basis is definite"...)

I don't agree with this change, though.

(Right now the spec only pays attention if 'width' is definite and "flex-basis:auto". I'm 95% certain this was an oversight, and having a definite 'flex-basis' should have the same effect.

I don't think it was an oversight -- the distinction is important.

With your change (allowing definite values in "flex-basis" to influence resolved min-width:auto), this will allow shrinkage below the min-content width (and cause overflow) when authors specify e.g. "flex: 1", which would make "flex: 1" much more dangerous to use.

As I recall, the whole idea of shorthands like "flex: 1" is that you can make your items grow equally from 0, with a guarantee that each item will be large enough to not have content overflowing. This change breaks that, and would likely cause backwards-compatibility headaches as a result.

Ugh, you're right. That's why I was only 95% sure. >_<

~TJ

# Tab Atkins Jr. (10 months ago)

On Tue, Mar 3, 2015 at 2:26 PM, Tab Atkins Jr. jackalmage@gmail.com wrote:

On Tue, Mar 3, 2015 at 10:13 AM, Daniel Holbert dholbert@mozilla.com wrote:

On 03/03/2015 09:25 AM, Tab Atkins Jr. wrote:

I literally checked in the fix for that yesterday, it's not showing up in the spec for some reason. I'll check this out.

Looks like it made it in now. ("If the item’s computed flex-basis is definite"...)

I don't agree with this change, though.

(Right now the spec only pays attention if 'width' is definite and "flex-basis:auto". I'm 95% certain this was an oversight, and having a definite 'flex-basis' should have the same effect.

I don't think it was an oversight -- the distinction is important.

With your change (allowing definite values in "flex-basis" to influence resolved min-width:auto), this will allow shrinkage below the min-content width (and cause overflow) when authors specify e.g. "flex: 1", which would make "flex: 1" much more dangerous to use.

As I recall, the whole idea of shorthands like "flex: 1" is that you can make your items grow equally from 0, with a guarantee that each item will be large enough to not have content overflowing. This change breaks that, and would likely cause backwards-compatibility headaches as a result.

Ugh, you're right. That's why I was only 95% sure. >_<

Okay, fixed. We reverted the the offending change, and fixed it properly by removing the requirement that 'flex-basis' be "content". If there is a specified size that's smaller than min-content, it should definitely win (this was already the case for "transferred" sizes, but I was being weird about specified size).

Quick use-case: <img src=foo width=40> If intrinsic width is 100px, an

author would still expect that it be allowed to shrink to 40px by default, regardless of whether flex-basis was "content" or some other length, same as an image with an intrinsic size of 40px.

~TJ

Want more features?

Request early access to our private beta of readable email premium.