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-align][css-sizing] Indefinite percentages in calc() are underspecified #2297

Closed
MatsPalmgren opened this issue Feb 10, 2018 · 10 comments
Closed

Comments

@MatsPalmgren
Copy link

The relevant spec text says:

Percentages resolve to zero when specified against a content-based size [...]

It's unclear to me what that means for calc()-expressions with percentage terms. For example, say we have an inline-grid with two columns, 50px each, and grid-column-gap: calc(10px + 20%).

My interpretation is that 20% ("Percentages") resolves to zero, and thus the gap resolves to 10px during intrinsic sizing, and thus the inline-size of the container is 110px. Is that correct?
Or should the entire calc()-expression resolve to zero?

@fantasai
Copy link
Collaborator

Yes. It says “percentages resolve to zero”, not “expressions involving percentages resolve to zero”. :)

I'm not sure the spec needs any fixing here, would you mind if I just close this invalid?

@MatsPalmgren
Copy link
Author

MatsPalmgren commented Feb 14, 2018

Here's the corresponding example in block layout:

<style>
span { display:inline-block; width:50px; height:10px; background:lime }
</style>
<div style="display:inline-block; border:1px solid;">
  <span style="margin-right:calc(10px + 20%)"></span><span></span>
</div>

In Chome - the width of the <div> is 100px and the right margin for the <span> is 30px, i.e. (10px + 0.2*100px). What you're suggesting is that the width should be 110px and the margin should be 10px + 0.2*110px. So are you saying that the block's intrinsic size here is wrong in Chrome?

(Firefox is still back-computing percentages in these cases, but we're removing that to comply with the recent CSSWG resolution.)

@mrego
Copy link
Member

mrego commented Feb 15, 2018

BTW, Edge and Safari have the same output than Chrome for the example above. The <div> has a width of 100px.

@MatsPalmgren
Copy link
Author

Well, if I change the above example to use padding instead of margin, like so:

<style>
span { display:inline-block; width:50px; height:10px; background:lime }
</style>
<div style="display:inline-block; border:1px solid;">
  <span style="padding-right:calc(10px + 20%)"></span><span></span>
</div>

then the <div> has a width of 110px in Chrome (and the padding ends up being 32px).
It seems weird to me that padding and margin percentages are resolved differently.

@fantasai fantasai changed the title [css-align] Percentage gaps are underspecified [css-align] Indefinite percentages in calc() are underspecified Mar 4, 2018
@fantasai fantasai changed the title [css-align] Indefinite percentages in calc() are underspecified [css-align][css-sizing] Indefinite percentages in calc() are underspecified Mar 4, 2018
@AmeliaBR
Copy link
Contributor

AmeliaBR commented Mar 4, 2018

From the author's side, I would definitely expect calc(10px + 20%) to always equal at least 10px, for margin or padding or anything else.

I also would very much prefer that contents inside a shrink-to-fit container don't end up adding extra spacing after the container has been fit, unless the percentages sum up to greater than 100%.

Based on those objectives, I see two acceptable approaches. Either:

  • calculate the container width using an algebra equation:

    • 100%*width = ∑(fixed widths) + ∑(percentage widths)*width
    • (100% - ∑(percentage widths) ) * width = ∑(fixed widths)
    • width = ∑(fixed widths) / (100% - ∑(percentage widths) )
    • AKA, for Mats' example, the width would be 110px/80% = 137.5px
  • Or, treat the reference for percentage widths as 0, calculate out the rest of the expression, and stick with it even after the container width is resolved. Less ideal, but simpler.

That said, the consistent behavior for all browsers I've tested for

  • width defined as a percentage + absolute length in shrink-to-fit containers is to treat the entire calc expression as zero when determining the parent container's width, but then evaluate the calc for the children normally after the parent width is set (so the child elements now overflow the too-small parent).

  • height defined as a percentage + absolute length in contexts where percentage height isn't defined (because of a fit-to-contents auto-height parent container) is to treat the entire calc expression as unresolvable, setting the height to auto.

I'm not sure where/if either of those behaviors are defined (CSS sizing says to refer to the individual layout modules for how to resolve percentages, and doesn't mention calc).

If height and width were consistent with each other, I'd argue that padding & margin should match the same behavior, too. But they aren't. They're a mess. So I refer again to my suggested solutions above, and wonder if there would be any compat issue with making width in a shrink-to-fit container behave similarly. (The algebra isn't that complicated, really…)

@dbaron
Copy link
Member

dbaron commented Mar 8, 2018

This is related to #1132, as mentioned in today's telecon.

@MatsPalmgren
Copy link
Author

(I've filed a Chromium bug about calc() margins here)

@fantasai
Copy link
Collaborator

Agenda+ to discuss zeroing out the percentage vs. zeroing out the entire expression, for margins/padding/gaps. The argument in favor of zeroing out the entire expression is that this is what seems to be implemented; the argument in favor of zeroing out the percentage is that it is more meaningful. (For the sizing properties (#1132), we fall back the entire expression to the initial value, but in that case the initial value is meaningful: it contributes the size of the content, which is usually a more important factor in sizing than the non-percentage parts of a calc expression. For margins and padding, however, the initial value is zero: zeroing out the percentage and scavenging the rest of the expression would be more meaningful.)

@css-meeting-bot
Copy link
Member

The Working Group just discussed calc() with percentages in margins/padding, and agreed to the following resolutions:

  • RESOLVED: zero out percentages on non-sizing use of calc
The full IRC log of that discussion <fantasai> Topic: calc() with percentages in margins/padding
<dael> github: https://github.com//issues/2297#issuecomment-376263348
<fantasai> github: https://github.com//issues/2297#issuecomment-376263348
<fantasai> rego: no
<rego> fantasai: :)
<dael> fantasai: it was to discuss 0ing out a % vs the entire expression. Example calc (10% + 10px) 0ing the entire expression is what's impl. 0ing the % is more meaningful. This is for purpose of calc intrinsic size calc of element.
<dael> dbaron: It's also continuous in terms of what happens when you have a calc that approaches 0 and you remove the calc.
<fantasai> Comment summarizing issue: https://github.com//issues/2297#issuecomment-376263348
<dael> TabAtkins: Are we okay with some properties having a different indefinite percent with calcs.
<dael> fantasai: I prefer 0 out the %
<dael> florian: Justification to 0 everything other then it's what we have
<dael> fantasai: Id din't hear anything.
<dael> Rossen: I agree with fantasai. 0ing the % makes more sense. Having a box model with tabbing and you'll 0 out %
<dael> fantasai: For size we ignore entire calc. We closed that in #1132. SOrry,w e throw out the calc and treat as auto. Fallback to initial value
<dael> fantasai: That makes snese for sizing in a way it doesn't here is if you fallback to the original that has some kind of meaning. In this case there's no meaningful value for margins and padding.
<dael> astearns: In only 0 out % for calc that's not sizing it's a slight descrepency.
<dael> fantasai: correct.
<dael> florian: We can do calc of 10%+10px is the same as 10px but we cant do auto+10px because that's not defined.
<Rossen> s/Having a box model with tabbing and you'll 0 out %/Having a box model with some % and non-% values results in the same logic, where we would zero out the % values and add the rest of the defined sizes/
<dael> astearns: Arguments against only 0ing out % on non-sizing use of calc
<dael> astearns: Obj?
<fantasai> (Florian was responding to Alan's question of why we throw out the expression for sizing props)
<dael> RESOLVED: zero out percentages on non-sizing use of calc

@fantasai
Copy link
Collaborator

OK, we've got edits in for zeroing out percentages in both margins/padding (in Sizing) and for gaps (in Alignment). Please re-open if the text is insufficiently clear, but otherwise I think we're closed out here.

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

No branches or pull requests

7 participants