Re: [css3-values] Three issues with calc()

On Thu, Apr 19, 2012 at 10:46 PM, Kang-Hao (Kenny) Lu
<kennyluck@csail.mit.edu> wrote:
> (12/04/20 6:32), Tab Atkins Jr. wrote:
>> Can you add numbers and dimensions?
>> ================================
>>
>> Right now, the spec explicitly prevents a number from being added to a
>> dimension.  In nearly all cases, this is a reasonable restriction,
>> because properties accept *either* numbers or dimensions, not both.
>>
>> The one exception (that I know of) is line-height, which accepts a
>> number that represents a kind of "used-value-time em", so that it has
>> good inheritance behavior.  This number is basically a length, though,
>> so its potentially sensical to say "line-height: calc(1 + .5em);"
>>
>> Are there more exceptions like this?
>
> Yes, border-image-* accept <number> to mean a multiple of border length.
>
>> If not, should we alter the restrictions on calc() to allow this sort
>> of use, or should we keep calc() simpler and just write this off as a
>> lone oddity?
>>
>> Note that if we *do* allow it, we need to define what to do with
>> properties other than line-height when they receive such a thing.
>> Currently it's a syntax error, so we can fall back to a more sensible
>> value.  If this was allowed in the grammar, though, we'd be past the
>> syntax error stage by the time we realized something was wrong,
>
> Can you elaborate on this? This seems pretty doable if you just change
>
>  # At ‘,’, ‘+’, or ‘-’, check that both sides have the same
>  # type; resolve to that type.
>
> to
>
>  | At ‘+’, or ‘-’, check that both sides have the same
>  | type or (one side is <number> and numbers are accepted in the
>  | context in which the expression is placed); resolve to that type
>  | if both sides have the same type or to the other non-<number> type
>  | in the latter case.
>
> (‘,’ should have been dropped along 'max()' and 'min()')
>
> , and these are parse time checks.
>
>> unless we violated layering and only allowed it while processing
>> 'line-height'.
>
> In some sense "numbers are accepted in the context in which the
> expression is placed" is indeed targeting 'line-height' and
> border-image-* but this is just similar to how we treat percentages,
> besides the obvious difference that <number>s can also be used as an
> operand of '*' and '/'.
>
> Having said that, I am slightly opposed to adding this behavior if no
> one can show that this is really needed since no matter what you say, '1
> + .5em' is a bit weird...

Actually, I came up with a stronger objection - numbers in line-height
and border-image effectively act like lengths with a special unit, and
would be converted to lengths at some point if you add them to a
proper length.

However, in the expression "line-height: calc(1 + 1em / 2 );", the "1"
is probably meant to be the "special line-height unit", but the 2 must
instead be a normal number.  This is confusing.

I think we should just disallow combining numbers and lengths like
this.  line-height and border-image can still use calc() expressions
that are solely numbers or solely lengths.


> A similar question: can you use keywords in calc()?
>
> If yes, an application of this is calc(medium * 3) for <font size=7>. I
> would certainly prefer this to 'xxx-large'.

Right now, you can't.  If you could, it would have to map to a length
there, and *3 might not necessarily be what you want.


>> Using attr() in calc()
>> ================
>>
>> Right now, the grammar for calc() explicitly requires NUMBER,
>> DIMENSION, or PERCENTAGE tokens.  It doesn't allow for other things
>> that might produce <number>, <percentage>, or dimension values, like
>> attr().
>>
>> Can we remove this restriction?  Note that if we do, we can no longer
>> guarantee that divide-by-0 errors will be caught at parse-time, since
>> attr() doesn't resolve until computed-value time.  We'll have to
>> define what happens when we hit these errors.  (I recommend treating
>> it like an invalid variable, and resetting the property to its initial
>> value.)
>
> Or you can just say attr() is not allowed at the right hand side of '/'.

Oh, good point.

~TJ

Received on Friday, 20 April 2012 18:06:57 UTC