Skip to content
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

[css-sizing] Decide how to handle min-width/min-height: auto for non-grid/flex items #2248

Closed
dholbert opened this issue Jan 31, 2018 · 16 comments

Comments

@dholbert
Copy link
Member

In #2230, the CSSWG resolved to make min-width/min-height: auto always compute to itself (though per #2230 (comment) , this was only with regards to flex and grid items).

What should happen for other elements? Right now the spec doesn't say (so it implies that it'd still compute to itself everywhere, which I don't think matches reality)... Previously it was defined as computing to 0 for these elements.

Suggestion: how about we say the resolved value of this auto keyword should be 0 for any non-grid/flex item. (This is basically what we've got implemented in Firefox, for non-grid/flex items -- i.e. we store auto internally in the computed style, and then we check the styles.) I'm guessing that might be what other engines do, too, though I don't know for sure (CC @rossen @cbiesinger)

@dholbert
Copy link
Member Author

dholbert commented Jan 31, 2018

Ah, now I see that the spec does actually say that auto computes to 0 for non-flex/grid items, in CSS-Sizing Section 3.2:

auto:
[...]
For min-width/min-height, specifies an automatic minimum size
Unless otherwise defined by the relevant layout module, this computes to zero.

I was misled/confused by the main definition of this property/value further up, in CSS-Sizing Section 3.1:

Name: | min-width, min-height
Initial: | auto
Computed value: | as specified, with lengths made absolute

I'm pretty sure the "lengths made absolute" text there does not affect "auto" (because "auto" is not a <length>, and also because we explicitly don't want to resolve it past auto on grid/flex items as discussed in #2230).

Perhaps we need some "see prose" caveat in the "Computed" line?

fantasai added a commit that referenced this issue Jan 31, 2018
…auto; pending deferrment to css-sizing if #2248 goes through.
fantasai added a commit that referenced this issue Jan 31, 2018
…ays, resolved value as zero where needed, per dholbert's proposal in #2248. Pending WG approval.
@dholbert
Copy link
Member Author

dholbert commented Feb 1, 2018

Per IRC conversation with @fantasai, how about: auto computes to auto always, but the resolved value of auto is 0 in some cases (really, most cases - it only stays "auto" for flex and grid items)

@fantasai
Copy link
Collaborator

fantasai commented Feb 1, 2018

@dholbert was pointing out that this is much easier to implement correctly, and is simpler to specify. It also neatly solves the problem of distinguishing between min-width: 0 and min-width: auto on bock/inline replaced elements (despite returning 0 from getComputedStyle), which we need to do to implement #1722

@dholbert
Copy link
Member Author

dholbert commented Feb 1, 2018

A few nits on the recent spec-tweak commit for this issue:
(1) "this behaves as zero" - IMO we should avoid "behaves" since it's too vague. I think you're talking about the used value being zero here, correct?

(2) "For backwards-compatibility, the resolved value of this keyword is zero for [...] block and inline boxes" -- this isn't strictly what you want to say, because flex items are "block boxes" (if they're display:block, and the resolved value of this keyword is not zero for them.

(3) Is the word "zero" OK to use here, or should we use 0? (Since 0 is an actual valid value for these properties, whereas "zero" is a bit vaguer (and does it mean 0% vs 0 vs 0px, etc.)

Suggestion: maybe you can address all three of these by replacing this with some language like:

Unless other layout modules explicitly define another behavior,
the used and resolved value of this keyword is 0.

...and then other layout modes (grid/flex) should be sure to define that the resolved value is auto, and the used value is the special complex thing. (RE "resolved value", maybe there's a way to describe all the CSS21 box-children in a sufficiently-precise way, but I'm not thinking of it right now. Basically you want to say "everything which is not a grid item and not a flex item and not a future similar thing", which is a hard concept to encapsulate.)

@foolip
Copy link
Member

foolip commented Feb 1, 2018

Here I am again, taking turns with @rakuco to look into a normative spec change without tests every week this quarter, to understand the challenges better.

This week I landed on 7272dc5 (a lot of commits in CSS, not randomly selected, but most other things I looked at were editorial, tested, or very new feautres)

That links here. Curiously, there isn't even a css-sizing directory in https://github.com/w3c/web-platform-tests/tree/master/css, so I'm probably missing something important about the nature of this spec. Maybe what it says can only be tested indirectly through its effect on other specs? The word "must" isn't used much, at least.

Anyway, 7272dc5 looks like something for which it would be straightforward to write a test using getComputedStyle or reftests, to see that the resolved style is one thing, but its effect is another. Presumably such tests would all pass since it's for backwards compat.

@dholbert, since you filed this issue, what do you think it'd take to determine whether this has been implemented or not, somewhere down the line? If this is actually a case that doesn't make sense to write tests for that's fine, I'd like to understand when that's the case too.

@dholbert
Copy link
Member Author

dholbert commented Feb 7, 2018

@dholbert, since you filed this issue, what do you think it'd take to determine whether this has been implemented or not, somewhere down the line? If

Here are the key things that'd be worth asserting, which are related to this issue (and please interpret "minWidth" as "both minWidth and minHeight, independently" below):

  • getComputedStyle(someDiv, "").minWidth == 0 for a child of a display:block or display:table element. (Any child of any non-{flex,grid} container, really.)
  • getComputedStyle(someDiv, "").minWidth == 'auto' for a child of a display:flex or display:grid element.

And then here's the subtle part...

  • getComputedStyle(someDiv, "").minWidth == 'auto' for a child of a display:flex or display:grid element, when there is an explicit min-width: inherit styling on that child.

That last point is the part that is new here as of 7272dc5. Previously, the spec required the parent container's default min-width to compute to 0, and since computed values are what's inherited, then the explicit min-width:inherit on the child would've made it inherit 0, rather than auto. So even though it was inheriting the default style from the parent, it would've ended up with a non-default style (since some processing was happening on the parent's computed value which was observable via inheritance). After 7272dc5, the "auto-->0" resolution will happen later, at resolved-value time, so the child would legitimately inherit auto (the same computed value it would've had by default anyway), and it'll return auto from getComputedStyle (since it's a flex item which preserves auto in its resolved min-width per 7272dc5.)

I suspect/expect that browsers already have the behavior that I'm proposing here, since it's strictly simpler (requiring less logic / special-casing at computation time). But I'm not sure.

@MatsPalmgren
Copy link

I was just updating some code dealing with min-width:auto and I'm wondering if min-width:N% with an indefinite percentage basis counts as auto in this context?
In particular, does Automatic Minimum Size apply?
https://drafts.csswg.org/css-grid/#min-size-auto

@dholbert
Copy link
Member Author

dholbert commented Feb 7, 2018

I tend to think that it should apply, though I don't think any spec text says that it would. And really, CSS2 has text saying that for min-height (which in CSS2 was the only one of the min-{size} properties that could have an indefinite basis), it falls back to '0':

The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the percentage value is treated as '0'

https://www.w3.org/TR/CSS22/visudet.html#propdef-min-height

I suspect "treated as '0'" there was really meant to signify "treated as the initial value". And so now, under that interpretation, this scenario should now fall back to auto-which-then-usually-gets-treated-as-0... This might want its own spec issue, though.

@astearns astearns added Agenda+ and removed Agenda+ labels Feb 13, 2018
@fantasai
Copy link
Collaborator

@dholbert @MatsPalmgren I think we should file that question as a separate issue. :)

@css-meeting-bot
Copy link
Member

The Working Group just discussed [css-sizing] Decide how to handle `min-width/min-height: auto` for non-grid/flex items, and agreed to the following resolutions:

  • RESOLVED: Accept the change in https://github.com/w3c/csswg-drafts/issues/2248#issuecomment-362114572
The full IRC log of that discussion <dael> Topic: [css-sizing] Decide how to handle `min-width/min-height: auto` for non-grid/flex items
<dael> github: https://github.com//issues/2248
<fantasai> https://github.com//issues/2248#issuecomment-362114572
<dael> fantasai: The issue is about what do we do with computed values on non-grid and non-flex items. Behave as 0. dholbert proposed auto keyword computes to itself on all display types, but the resolved value should be 0.
<dael> fantasai: This has a couple of advantages. One is that it makes the computed value easier to compute, the keyword isn't based on display type information. Second advantage is there was some behavior we were trying to resolve for anotehr issue which required us to distinguish between auto and 0 min sizes on elemnts that are no flex and grid so being able to refer to that is good.
<dholbert> *resolved & used (i guess)
<dael> fantasai: Disadvantage if you're animating from initial value of assumed 0 on the min-height and min-width, that breaks.
<dael> fantasai: No sure how many people are animating that and, if they are, assuming initial value of 0.
<dael> fantasai: I think we should take proposal, but want to hear from group. Toward the end of the issue there's discussion about a separate item that needs to file separately.
<dael> astearns: Other opinions?
<dael> astearns: Proposal is have the computed value be auto but the used value be 0?
<dael> fantasai: Used value is 0. Resolved value would be 0. CHange...currently computed value is 0, computed value remains as the keyword auto. If you use getComputedStyle we'll return 0 for backwards compat
<dael> fantasai: Kinda like we do for width where auto computes to self but getComputedStyle returns 0
<dael> astearns: Objections to this change?
<dael> RESOLVED: Accept the change in https://github.com//issues/2248#issuecomment-362114572
@dholbert
Copy link
Member Author

It's possible that implementations already match this new spec text, actually! Here's a testcase for this behavior:
https://jsfiddle.net/atz4t2tc/
(Look at the JS console for results)

In Firefox (nightly) and latest Chrome and Edge, that gives me:

gCS for initial value, on NON flex item: 0px
gCS for initial value, on flex item: auto
gCS for inherited initial value, on flex item: auto

Per the previous spec text, I was expecting that the last line there would say '0px' (since computed values are what are inherited, and per previous spec text, '0px' would be the computed value of the initial 'auto' on the parent of this flex item -- and so '0px' is what would inherit to the flex item that has explicit 'min-width:inherit'). But maybe the previous spec text's expectations about this edge-case were silly enough that nobody ever implemented them. :)

@gsnedders
Copy link
Contributor

That links here. Curiously, there isn't even a css-sizing directory in https://github.com/w3c/web-platform-tests/tree/master/css, so I'm probably missing something important about the nature of this spec. Maybe what it says can only be tested indirectly through its effect on other specs? The word "must" isn't used much, at least.

Basically all the css-sizing tests are within css/CSS2.

@fantasai
Copy link
Collaborator

fantasai commented Mar 4, 2018

@dholbert Replying to #2248 (comment) ...
(1) OK, changed wording.
(2) Flex items are not block boxes... they can be block containers, but a block box is a block-level block container, and is specifically the CSS2.1 display type known as a block. :)
(3) OK, switched to ''0''.

Current prose is

For 'min-width'/'min-height', specifies an automatic minimum size. Unless otherwise defined by the relevant layout module, however, it resolves to a used value of ''0''.

Didn't add the resolved value bit into the general definition, because we do want that to remain as an exception for the CSS2.1 display types only.

@fantasai
Copy link
Collaborator

fantasai commented Mar 4, 2018

Filed #2384 for follow-up to @MatsPalmgren's #2248 (comment) ; please follow-up there with any opinions. :) Closing out this issue, assuming @dholbert is satisfied with the wording now.

@fantasai fantasai closed this as completed Mar 4, 2018
@dholbert
Copy link
Member Author

dholbert commented Mar 6, 2018

This seems fine, yeah. I see you're right about flex items not being block boxes, since CSS2.1 defines block boxes as being a subcategory of block-level boxes, which are defined as boxes that "participate in a block formatting context".

One minor issue that still remains, with the "block and inline boxes" special callout -- technically, the new spec text doesn't define what to do with min-width:auto on table parts that honor min-width -- for example td, col, and caption all seem to honor min-width as shown here: https://jsfiddle.net/fnkdoeng/

Those table parts aren't block boxes, nor are they inline boxes, so the css-sizing spec doesn't currently define what the default min-width:auto keyword does there. Maybe this is something that can be defined in the css-tables-3 spec though?

@fantasai
Copy link
Collaborator

fantasai commented Mar 29, 2018

@dholbert I think the current text in Sizing covers table parts adequately: https://drafts.csswg.org/css-sizing-3/#valdef-width-auto

For min-width/min-height, specifies an automatic minimum size. Unless otherwise defined by the relevant layout module, however, it resolves to a used value of 0.

For backwards-compatibility, the resolved value of this keyword is zero for boxes of all [CSS2] display types: block and inline boxes, inline blocks, and all the table layout boxes.

There's a separate question of how tables interpret min-width, which is up to the css-tables-3 spec, yes. IIRC, the effective minimum is the larger of the min-width and the min-content width.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment