Skip to content

[css-sizing-3] Content contribution of min-inline-size:fit-content and max-inline-size:fit-content #10721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bfgeek opened this issue Aug 9, 2024 · 8 comments

Comments

@bfgeek
Copy link

bfgeek commented Aug 9, 2024

We came across this from a bug report submitted to us, and basically it comes down to these cases:

<!DOCTYPE html>
<div style="width: fit-content; border: solid 10px;">
  <div style="max-width: fit-content; width: 100000px;">
    abc def ehg
  </div>
</div>

https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=12976

<!DOCTYPE html>
<div style="width: fit-content; border: solid 10px;">
  <div style="min-width: fit-content; width: 10px;">
    abc def ehg
  </div>
</div>

https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=12977

Basically:

  • For Blink - The available-size is indefinite (during the content contribution calculation) so we'll throw away the fit-content, and just treat the min-inline-size, and max-inline-size as 0, and Infinity respectively.
  • For Gecko - The available-size is indefinite; for the min-inline-size - fit-content becomes min-content, and for max-inline-size - fit-content becomes max-content.

Gecko's behaviour here is reasonable (at least to me), but isn't in the spec (from my reading).
cc/ @tabatkins

@bfgeek bfgeek added the css-sizing-3 Current Work label Aug 9, 2024
@dbaron
Copy link
Member

dbaron commented Aug 9, 2024

(See the bug report that Ian mentioned.)

@dbaron
Copy link
Member

dbaron commented Aug 9, 2024

For what it's worth, the Gecko behavior dates back to the initial implementation of fit-content under the name -moz-shrink-wrap back in 2007.

@dbaron
Copy link
Member

dbaron commented Aug 9, 2024

(And this behavior was in the early spec draft that I had for these values, going back to the May 2007 draft. I guess it never found its way into css-sizing, though.)

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 9, 2024
This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
@tabatkins
Copy link
Member

(I discussed this with Ian in person.)

Yeah, the Firefox behavior isn't in the spec; Chrome is more correct in ignoring the unresolvable size under the min/max size constraint.

But I think Firefox's behavior makes more sense. It's not perfect, but it seems closer to what the author would expect. I think it's safe too, in that it produces a min size that's smaller (or equal) to what the eventual "real" size is, and a max size that's larger (or equal), so you won't run into situations where the min size is larger than the eventual size or vice versa.

aarongable pushed a commit to chromium/chromium that referenced this issue Aug 9, 2024
This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1339852}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 9, 2024
This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1339852}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 9, 2024
This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1339852}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Aug 11, 2024
…ize/max-inline-size behaviour., a=testonly

Automatic update from web-platform-tests
[layout] Change fit-content min-inline-size/max-inline-size behaviour.

This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1339852}

--

wpt-commits: 09f3cc9dc689e3fdd1e70d1dbde617046620872a
wpt-pr: 47555
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Aug 12, 2024
…ize/max-inline-size behaviour., a=testonly

Automatic update from web-platform-tests
[layout] Change fit-content min-inline-size/max-inline-size behaviour.

This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1339852}

--

wpt-commits: 09f3cc9dc689e3fdd1e70d1dbde617046620872a
wpt-pr: 47555
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Aug 23, 2024
…ize/max-inline-size behaviour., a=testonly

Automatic update from web-platform-tests
[layout] Change fit-content min-inline-size/max-inline-size behaviour.

This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <dbaronchromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrickchromium.org>
Cr-Commit-Position: refs/heads/main{#1339852}

--

wpt-commits: 09f3cc9dc689e3fdd1e70d1dbde617046620872a
wpt-pr: 47555

UltraBlame original commit: 186af642ec9e9cad4990b0518890566a2b7da429
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Aug 23, 2024
…ize/max-inline-size behaviour., a=testonly

Automatic update from web-platform-tests
[layout] Change fit-content min-inline-size/max-inline-size behaviour.

This (by my reading how any of this works FWIW) doesn't defined by
the specification, but Gecko's behaviour here seems reasonable.

Previously during the content-contribution calculation we'd treat
fit-content as indefinite, which result in:
 - max-inline-size == LayoutUnit::Max()
 - min-inline-size == border_padding.

Gecko instead (if the available-size is indefinite) does:
 - max-inline-size:fit-content use max-content instead.
 - min-inline-size:fit-content use min-content instead.

This seems like a better behaviour.

Adds two tentative tests, and I've filed the relevant CSSWG issue:
w3c/csswg-drafts#10721

Fixed: 358393344
Change-Id: Ia7a350b241af4e0301e14dc812f2e04b41441076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5778080
Reviewed-by: David Baron <dbaronchromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrickchromium.org>
Cr-Commit-Position: refs/heads/main{#1339852}

--

wpt-commits: 09f3cc9dc689e3fdd1e70d1dbde617046620872a
wpt-pr: 47555

UltraBlame original commit: 186af642ec9e9cad4990b0518890566a2b7da429
@Loirooriol
Copy link
Contributor

Loirooriol commented Oct 15, 2024

I don't like this much, why should e.g. max-width: fit-content be like max-content instead of fitting into the container?

If we are not going to treat it as a cyclic percentage, I would rather say that fit-content:

  • Should behave as min-content for the purpose of computing the min-content contribution
  • Should behave as max-content for the purpose of computing the max-content contribution

So max-width: fit-content; width: 100000px should just behave like width: fit-content.

Servo Gecko, Blink WebKit
image

https://www.software.hixie.ch/utilities/js/live-dom-viewer/saved/13201

Source code
<!DOCTYPE html>
<div style="width: 2ch; border: 1ch solid magenta; font-family: monospace">
  <div style="display: inline-block; border: solid 1ch;">
    <div style="display: inline-block; width: 100000ch; max-width: fit-content;">
      abc def ehg
    </div>
  </div>
</div>
<br>
<div style="width: 9ch; border: 1ch solid magenta; font-family: monospace">
  <div style="display: inline-block; border: solid 1ch;">
    <div style="display: inline-block; width: 100000ch; max-width: fit-content;">
      abc def ehg
    </div>
  </div>
</div>
<br>
<div style="width: 16ch; border: 1ch solid magenta; font-family: monospace">
  <div style="display: inline-block; border: solid 1ch;">
    <div style="display: inline-block; width: 100000ch; max-width: fit-content;">
      abc def ehg
    </div>
  </div>
</div>

Gecko and Blink forcing overflow when min-content wouldn't require it seems against the nature of fit-content.

@Loirooriol
Copy link
Contributor

I guess treating max-width: fit-content as max-width: max-content follows from the fit-content formula

clamp(min-content, stretch, max-content)

if you treat an indefinite max-width: stretch as infinity. But see #11006, the spec says to treat an indefinite stretch as an automatic size.

@Loirooriol
Copy link
Contributor

My proposal above seems to match the specified behavior (https://drafts.csswg.org/css-sizing-3/#fit-content-size)

fit-content size
If the available space in a given axis is definite, [...]. When sizing under a min-content constraint, equal to the min-content size. Otherwise, equal to the max-content size in that axis.

@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meeting Jan 22, 2025
@Loirooriol Loirooriol moved this from Regular agenda items to FTF agenda items in CSSWG January 2025 meeting Jan 23, 2025
@astearns astearns moved this from FTF agenda items to Thursday morning in CSSWG January 2025 meeting Jan 28, 2025
@astearns astearns moved this from Thursday morning to FTF agenda items in CSSWG January 2025 meeting Jan 28, 2025
@astearns astearns moved this from FTF agenda items to Friday morning in CSSWG January 2025 meeting Jan 28, 2025
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-sizing-3] Content contribution of min-inline-size:fit-content and max-inline-size:fit-content, and agreed to the following:

  • RESOLVED: No normative change to spec, but add example like Oriol's and make the implication clearer in the spec.
The full IRC log of that discussion <TabAtkins> oriol: when you're computing intrinsic cocntirubtion of a fit-content element, what should happen?
<TabAtkins> oriol: if you use fit-content on the preferred sizing property, it's clear that for the purpose of computing min-content contribution, you treat it as min-content; for max-content contrib, you treat it as max-content
<TabAtkins> oriol: but if you use this keyword on min or max sizing properties, it's less clear what shoudl happen
<TabAtkins> oriol: what webkit does is it just ignores the keyword, so in a min property it treats as 0, in max it treats it as none
<TabAtkins> oriol: blink used to have the same behavior, but changed to align with firefox
<TabAtkins> oriol: firefox beahvior is, when computing intrinsic contribs, fit-content acts as min-content in min sizing property, and as max-content in a max sizing property
<TabAtkins> oriol: i was implementing in servo and i think there's a better behavior, and i think it's what's actually specified in the spec, and is a bit simpler to implement
<oriol> https://github.com//issues/10721#issuecomment-2414743959
<TabAtkins> oriol: some testcases ^^^
<TabAtkins> oriol: in this testcase, magenta wrapper has a fixed width - first very narrow, then between, then wider
<fantasai> <3 Oriol's examples
<TabAtkins> oriol: element with black border is inline-block, so shrink-to-fit
<TabAtkins> oriol: the inline-block contains one element with `width` to a huge amount, and max-width:fit-content
<TabAtkins> oriol: so webkit ignores the max-width so the width makes it all explode
<TabAtkins> oriol: gecko and blink treat it as max-content, so the inline-block is always sized as max-content
<TabAtkins> oriol: i think the servo column is better. do the smae for the three sizing props
<TabAtkins> oriol: you always treat it as min-content when doing min-content contribution, and similar for max, for all three properties
<TabAtkins> oriol: so if magenta wrapper is narrow you'll use the min-content contribution, if wide you'll use the max-content contribution, and if between it'll be between
<TabAtkins> oriol: i think this is a better match for fit-content, trying to fit into the container
<TabAtkins> oriol: so i propose the spec is right, and servo is right, and other browsers should match
<astearns> ack fantasai
<TabAtkins> fantasai: thanks for the fantastic examples
<TabAtkins> fantasai: as editor, i think Servo's impl is correct. it reflects the author's request
<TabAtkins> fantasai: in 2.1's definition of min/max sizing properties, it says you literally run layout by subbing in the value for 'width' and then clamp appropriately; this matches that behavior as well
<TabAtkins> iank_: I think this is likely fine.
<TabAtkins> iank_: hopefully no compat issues, but on the surface it's not too difficult for us to do
<TabAtkins> astearns: so are we resolving the spec is correct?
<TabAtkins> oriol: yes
<TabAtkins> iank_: it's not obvious to me that the spec is correct, so clarifying would be good for the future
<TabAtkins> oriol: at end of th eissue i posted the quote of the spec that i think is backing the servo behavior, we can clarify or add some examples
<TabAtkins> examples++
<TabAtkins> fantasai: the spec doesn't make a distinction between what fit-content size means based on property, so i don't think it can support an interpretation that it works differentyl in the different properties
<TabAtkins> astearns: so let's make that explicit
<TabAtkins> astearns: so proposed resolution is we add examples like Oriol's and make the implication clear in the spec
<TabAtkins> RESOLVED: No normative change to spec, but add example like Oriol's and make the implication clearer in the spec.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 17, 2025
fit-content for the min-contribution calculation should be treated as
min-content, and for the max-contribution max-content. As per:
w3c/csswg-drafts#10721

Fixes tests for min-width:stretch to resolve as zero, and
max-width:stretch as infinity as per:
w3c/csswg-drafts#11006

Fixed: 402760799
Change-Id: I109ffdd057db45236e3f95f174e0ab8b684060d5
aarongable pushed a commit to chromium/chromium that referenced this issue Mar 17, 2025
fit-content for the min-contribution calculation should be treated as
min-content, and for the max-contribution max-content. As per:
w3c/csswg-drafts#10721

Fixes tests for min-width:stretch to resolve as zero, and
max-width:stretch as infinity as per:
w3c/csswg-drafts#11006

Fixed: 402760799
Change-Id: I109ffdd057db45236e3f95f174e0ab8b684060d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6357845
Reviewed-by: Morten Stenshorne <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1433610}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 17, 2025
fit-content for the min-contribution calculation should be treated as
min-content, and for the max-contribution max-content. As per:
w3c/csswg-drafts#10721

Fixes tests for min-width:stretch to resolve as zero, and
max-width:stretch as infinity as per:
w3c/csswg-drafts#11006

Fixed: 402760799
Change-Id: I109ffdd057db45236e3f95f174e0ab8b684060d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6357845
Reviewed-by: Morten Stenshorne <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1433610}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 17, 2025
fit-content for the min-contribution calculation should be treated as
min-content, and for the max-contribution max-content. As per:
w3c/csswg-drafts#10721

Fixes tests for min-width:stretch to resolve as zero, and
max-width:stretch as infinity as per:
w3c/csswg-drafts#11006

Fixed: 402760799
Change-Id: I109ffdd057db45236e3f95f174e0ab8b684060d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6357845
Reviewed-by: Morten Stenshorne <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1433610}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Mar 18, 2025
…ne-sizes for contributions., a=testonly

Automatic update from web-platform-tests
[layout] Fix fit-content on min/max inline-sizes for contributions.

fit-content for the min-contribution calculation should be treated as
min-content, and for the max-contribution max-content. As per:
w3c/csswg-drafts#10721

Fixes tests for min-width:stretch to resolve as zero, and
max-width:stretch as infinity as per:
w3c/csswg-drafts#11006

Fixed: 402760799
Change-Id: I109ffdd057db45236e3f95f174e0ab8b684060d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6357845
Reviewed-by: Morten Stenshorne <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1433610}

--

wpt-commits: bd81ee4af33248ccd3a153a9389876d8f4b51166
wpt-pr: 51392
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Friday morning
Development

No branches or pull requests

6 participants