[CSSWG] Minutes Sizing Breakout 2025-02-19 [css-sizing]

=========================================
  These are the official CSSWG minutes.
  Unless you're correcting the minutes,
 please respond by starting a new thread
   with an appropriate subject line.
=========================================


CSS Sizing Breakout
-------------------

  - RESOLVED: Fixed table layout is triggered except when inline-size
              is auto (Issue #10937: What sizing keywords allow fixed
              table mode?)
  - RESOLVED: Accept proposal (Issue #11044: How does height: stretch
              interact with margin collapsing with parent)
  - RESOLVED: See if implementations can match the spec and revisit
              issue later (Issue #11452: Nobody follows the spec about
              cyclic percentages in preferred&max sizing properties of
              replaced element)
  - RESOLVED: min-size: stretch behaves as zero, max-size; stretch as
              infinity, when in an indefinite container (Issue #11006:
              Does indefinite `stretch` behave as automatic size or as
              initial value?)

===== FULL MEETING MINUTES ======

Agenda: https://lists.w3.org/Archives/Public/www-style/2025Feb/0009.html

Present:
  Tab Atkins-Bittner
  Oriol Brufau
  Emilio Cobos Álvarez
  Elika Etemad
  Ian Kilpatrick
  Roman Komarov
  Alan Stearns
  Miriam Suzanne

Scribe: fantasai
Scribe's scribe: oriol, TabAtkins

CSS Sizing
==========

What sizing keywords allow fixed table mode?
--------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/10937

  iank: When we trigger fixed table layout depends on the inline-size
        property.
  iank: This is inconsistent between implementations and spec
  iank: As we've added more keywords, it's also changed
  iank: Gecko and Blink are consistent with each other, and spec and
        WebKit are consistent
  iank: but spec wasn't kept up to date
  iank: Tables generally have a lot of behavior changes when something
        isn't 'auto'
  iank: This triggers for sizing columns, rows, etc.
  iank: We're already pretty close on 2 implementations
  iank: so easiest resolution would be condition on if inline-size is
        'auto'

  oriol: I like this proposed resolution. Note WebKit was aligned with
         the spec when I filed the issue, but they recently aligned
         'fill-available' to align with Blink and Gecko
  iank: Also a difference between... if inline-size is not auto, need a
        different behavior. That's the easiest behavior.
  iank: Gecko and Blink also trigger on max-content, but don't see a
        reason to do that.

  fantasai: I'm trying to think the underlying logic of treating
            max-content different than min-content, seems weird
  fantasai: allowing fixed layout for stretch and such makes sense
  fantasai: what does 'intrinsic' mean?
  oriol: Webkit's non-standard thing, unsure what it's doing
  fantasai: I don't understand what min-intrinsic means
  iank: We're advocating to have max-content match min-content/
        fit-content
  iank: Logic is if inline-size is not auto, trigger fixed layout
        behavior

  emilio: Looked up the special case, and goes back to the initial
          implementation by dbaron. But I also don't see any reason to
          special-case max-content and not other keywords. Maybe dbaron
          remembers
  <emilio> https://bugzilla.mozilla.org/show_bug.cgi?id=311415

  astearns: So we're trying to turn table all green except for 'auto'
            value?
  iank: That's correct.
  astearns: Biggest change in WebKit, but changes all browsers

  fantasai: what does fixed layout do for max-content?
  iank: It's not fixed layout, it's also intrinsically sized, but
        slightly different way
  <TabAtkins> iirc, it's mainly just "only pay attention to the first
              row", right?
  iank: It's very confusing
  iank: At one point you didn't need to run intrinsic sizing, but we're
        well past that at this point
  fantasai: Original justification was that you could do single-pass
            layout on it
  iank: Definitely no longer possible
  iank: We definitely compute intrinsic sizes for fixed table layout
  <TabAtkins> (i remember using it to get reasonable column sizes based
              on the headings, rather than the body cells)

  fantasai: If you wave a huge table that is huge to layout, can you
            use fixed to get that?
  iank: We'd have to add a new table layout keyword for that to happen.
        Don't think it's possible today.
  oriol: Still can bring some perf optimization, since you're ignoring
         measures of cells not in the first row, so may be faster
  fantasai: So if doing max-content fixed layout, would size for first
            row and then lay out table following that?
  oriol: in servo we don't do anything special except compute different
         measures for the tracks
  fantasai: If by "compute different measures" you mean ignore the cell
            contents, that's pretty significant difference.
  oriol: Whether table is fixed or not is not relevant to intrinsic
         sizes of table, or the way you compute them ... can affect the
         final result
  iank: Difference between fixed vs auto layout is minimal, they both
        have a max-content size and min-content size
  iank: From my point of view there's not a good perf optimization
        benefit to it given where web-compat is now
  iank: you always need to determine min-content size on everything
  iank: there's a max-content size
  florian: Is it used for perf? Or is it used when just tuning for
           first row?
  iank: Min constraint doesn't even restrict to first row.
  <miriam> (yes, Florian's comment matches my experience of the
           use-case)

  astearns: Since the issue isn't about how it generally works, but
            what triggers it, can we resolve on it works for everything
            except auto?
  [general silence]

  RESOLVED: fixed table layout is triggered except when inline-size
            is auto

How does height: stretch interact with margin collapsing with parent
--------------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11044

  TabAtkins: The spec for height:stretch around for awhile. While
             trying to implement, we ran into some issues with its
             definition
  TabAtkins: mainly what info it's trying to rely on and when that info
             would be available
  TabAtkins: also consistency issues
  TabAtkins: big problem is that the rules as stated can result in
             multiple children getting different sizes based on where
             they are in the element
  TabAtkins: or a single element changing size depending on presence of
             other elements
  TabAtkins: means that mutating DOM can change expectations for what
             height should be
  TabAtkins: After working through implications, settled on proposal
             that addresses the core use cases but simplifies inputs to
             stable
  TabAtkins: height:stretch always fills parent's content box, taking
             into account child's own mbp
  TabAtkins: if parent settings would prevent collapsing, we assume no
             collapsing; otherwise assume collapsing
  TabAtkins: same thing for bottom margin
  TabAtkins: in most cases this will do what you want
  TabAtkins: if parent has border, child will fit exactly inside
             considering its own margins
  TabAtkins: if no border, child will fit exactly inside ignoring its
             own margins
  TabAtkins: If you're doing this for multiple elements, all stretched
             elements will be the same size
  TabAtkins: There are a few cases where this will cause item to be a
             little too large
  TabAtkins: e.g. assumptions about collapsing were wrong
  TabAtkins: e.g. sibling prevents collapsing
  TabAtkins: but at that point you're violating the base contract of
             this feature, which is that you're the only thing in the
             parent
  TabAtkins: other cases you get the sizing you expect

  fantasai: The intention we were going with is that you just pretend
            the item is the only thing in the box and do something
            simple about margin collapse
  fantasai: in particular, a fixed height on the parent would normally
            prevent margin collapse but would truncate the margin; we
            didn't want that to cause non-collapse behavior for
            calculating the child's size
  fantasai: I think Tab's proposal is basically a more correct version
            of what the spec is trying to do

  astearns: No compat concerns?
  TabAtkins: No public implementations yet
  iank: For stretch keyword, no one has shipped yet
  iank: Blink will ship this with stretch, and then try to make
        -webkit-fill-available match it as a separate step
  iank: I don't think we'll run into issues due to current non-interop
  astearns: proposed to adopt Tab's proposal

  RESOLVED: Accept proposal

Nobody follows the spec about cyclic percentages in preferred&max
    sizing properties of replaced element
-----------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11452

  oriol: When calculating intrinsic contributions, percentages are
         cyclic. Spec says what to do.
  oriol: In preferred and max properties, they typically behave as
         initial value of the property
  oriol: But spec says if element is replaced, for min-content
         contribution only, you resolve the cyclic percentages against
         zero
  oriol: It doesn't say treat everything as zero, just resolve
         percentages as zero
  oriol: so calc(length + percentage) would still have the length
  oriol: but nobody implements this
  oriol: Treating as zero instead
  oriol: This avoids some minor problems, e.g. it's possible given spec
         that the min-content contribution would be larger than when
         properly resolved
  oriol: Given everyone treats as zero, probably should spec that
  <TabAtkins> Yeah, unless there's a compat restriction, treating
              `calc(100px + 0%)` as 0 is a ton of nonsense, that's what
              we were trying to avoid. :(

  fantasai: Intention of spec was to preserve the author-specified
            minimum as much as we could
  fantasai: e.g. if they wanted min-width: calc(10px + 5%)
  fantasai: we'd give them the 10px, which is what they'd get in a
            zero-sized container
  fantasai: I don't know if it's Web-compatible, but if it is, I'd
            prefer to follow the spec.
  oriol: Would prefer to match spec to reality, unless people are
         willing to change.
  fantasai: Ian, what do you think the web-compat is likely on this one?
  fantasai: because I think the spec behavior is better
  iank: Not really sure what Web-compat would be. Would be pretty
        straightforward to query how often calc() appears inside a
        min-width/height
  iank: though wouldn't know how often we're depending on the intrinsic
        size there
  emilio: What about min greater than max... need to compute both
  emilio: and do extra work
  emilio: Suppose you're in this case where min is bigger than max,
          spec says we clamp it
  emilio: then we also need to compute the max
  fantasai: Min trumps max, so... why?
  emilio: If you set min-width: max-content; and width: min-content; ...
  emilio: that doesn't make sense
  emilio: As long as we don't change what clamps what it's fine
  emilio: Does the spec define that?
  iank: Falls out
  iank: Only really important for content contributions, not for
        min-content/max-content values
  emilio: Would be nice if max-content didn't give me a value smaller
          than min-content
  iank: max-content on an element itself isn't using min-width, it's
        only for the content contribution
  emilio: You have 2 identical elements, and say you hit this case
  emilio: style one with width: max-content; and one with width:
          min-content;
  emilio: ...
  emilio: maybe it's not an issue
  oriol: For example CSS Grid etc. assume min-content is smaller than
         max-content
  oriol: but I wrote a testcase where min-content contribution is 100px
         and max-content contribution is 50px
  oriol: you could get a smaller sized [missed]
  oriol: which seems weird
  emilio: Unfortunate... maybe ok if it already happens
  iank: It's possible, so we have to clamp them all the time. E.g.
        happens with negative margins.
  iank: we have to clamp max-content by min-content already

  astearns: I think I'm hearing we're not that interested in speccing
            reality in this case, prefer trying to get implementations
            to match the spec. Anyone willing to volunteer to
            experiment with this?
  emilio: I do have a slight preference to spec reality, but not
          opposed to trying this out
  emilio: also don't think I'll have time in the short term
  iank: I would also prefer to spec reality, but we could try to do it.
        Not that difficult for us to do this change.
  iank: could see what fallout there is
  fantasai: My feeling from authoring perspective is it makes a bit
            more sense if we can do it as specced
  fantasai: so that's where I'm at
  astearns: That's where I'm at, too.
  astearns: We could leave this issue open, invite experimentation, and
            come back to it in some number of months and see if anyone
            had a chance to try implementing the spec
  fantasai: That seems reasonable
  astearns: Does that work for you oriol?
  oriol: That's fine, just having a spec that doesn't reflect reality...
  oriol: especially following one, we in servo implemented the spec,
         and then realized we're not doing the same as other browsers
  oriol: not great for new browsers
  astearns: So you had done some experiments! Did you notice the
            difference? Inform compat?
  oriol: Maybe I should have merged the two issues...
  oriol: This one is for replaced elements, we did what other
         browsers do
  oriol: The next issue is about min size property for all elements
  oriol: We implemented the spec, and we are failing some WPT tests
         because these tests are expecting the browsers behavior and
         not the spec
  astearns: Test failures are one thing, because tests can have mistakes
  astearns: those test failures, have you seen what difference it would
            make from authoring perspective?
  oriol: I don't recall much
  oriol: not many tests, maybe 2 tests
  oriol: I think it wasn't very important
  oriol: but Servo is very experimental, can't use to browse real
         websites, so can't inform about web-compat
  oriol: In the other issue I linked some tests

  astearns: Let's table this issue for now see if we can have
            implementations follow the spec
  astearns: because I do agree from author perspective it is better to
            preserve at least some of the intent
  astearns: Should we do the same for the next issue?
  oriol: Yes, it can be the same
  astearns: OK, for these we will see if we can get implementations to
            match and revisit

  RESOLVED: See if implementations can match the spec and revisit issue
            later

Does indefinite `stretch` behave as automatic size or as
    initial value?
--------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11006

  oriol: Spec says stretch size is same behavior as automatic size +
         stretch alignment
  oriol: but it doesn't restrict this definition to preferred size
         property
  oriol: my understanding is you can set this in min or max property
  oriol: I've been implementing in servo, but doesn't match other
         browsers
  oriol: they don't support keywords in the block axis
  oriol: it ignores it in min-size, and in max-size it treats it as none
  oriol: from what davidsgrogan said, this was the intention of the
         editors of the spec ?
  fantasai: That seems a bit weird, if we're not supporting it we just
            shouldn't parse it
  oriol: State is inconsistent because actively changing implementations
  oriol: in Firefox these keywords work in inline axis, but not in
         block one
  oriol: and then you need to parse the value because you don't know
         the writing mode
  oriol: Blink obeys these keywords in both axes

  fantasai: Is there a reason we can't make it mean what it says in the
            min/max properties?
  fantasai: from an authors' perspective, stretch means "I want to fill
            the container"
  fantasai: so if you said "I would like this box to have a width of
            100px but a max-width of stretch", then it should be 100px
            if the container is larger than 100px but filling it
            exactly if it's smaller
  fantasai: that's what I'd expect
  oriol: This is just when the stretch size is indefinite, so we don't
         know the container size
  oriol: so it happens in the block axis in block layout
  fantasai: Ah, in that case that make sense
  oriol: Ian says 'stretch' is an extrinsic value, would be weird to
         treat it as intrinsic.
  oriol: what I did in servo is slightly simpler to implement, but
         aligning with Blink is ok
  astearns: Resolving stretch to zero, infinity when available size is
            indefinite
  astearns: Can we resolve on it?
  astearns: Any objections

  RESOLVED: min-size: stretch behaves as zero, max-size; stretch as
            infinity, when in an indefinite container

Received on Thursday, 20 February 2025 00:28:07 UTC