Skip to content

[css-align][css-sizing] Indefinite percentages in calc() are underspecified #2297

Closed

Description

@MatsPalmgren

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?

Activity

  1. fantasai commented on Feb 14, 2018

    @fantasai
    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?

  2. MatsPalmgren commented on Feb 14, 2018

    @MatsPalmgren
    Author

    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.)

  3. mrego commented on Feb 15, 2018

    @mrego
    Member

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

  4. MatsPalmgren commented on Mar 1, 2018

    @MatsPalmgren
    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.

  5. changed the title [-][css-align] Percentage gaps are underspecified[/-] [+][css-align] Indefinite percentages in calc() are underspecified[/+] on Mar 4, 2018
  6. changed the title [-][css-align] Indefinite percentages in calc() are underspecified[/-] [+][css-align][css-sizing] Indefinite percentages in calc() are underspecified[/+] on Mar 4, 2018
  7. AmeliaBR commented on Mar 4, 2018

    @AmeliaBR
    Contributor

    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…)

  8. dbaron commented on Mar 8, 2018

    @dbaron
    Member

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

  9. MatsPalmgren commented on Mar 17, 2018

    @MatsPalmgren
    Author

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

  10. fantasai commented on Mar 26, 2018

    @fantasai
    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.)

  11. css-meeting-bot commented on Apr 10, 2018

    @css-meeting-bot
    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
  12. fantasai commented on Apr 23, 2018

    @fantasai
    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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions