- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Thu, 10 Apr 2014 14:20:14 -0700
- To: Zack Weinberg <zackw@panix.com>
- Cc: www-style list <www-style@w3.org>

On Thu, Apr 10, 2014 at 12:43 PM, Zack Weinberg <zackw@panix.com> wrote: > I brought up the question of being able to divide two <length>s in > calc() earlier this week, along with min/max expressions. I'm > convinced min/max are Too Hard for right now, but I think it's not too > hard to specify enough unit algebra to make <length> ratios feasible. > Here is a concrete proposal relative to the current ED. > > In section 8.1.1 (calc() syntax): > > - product : unit [ S* [ "*" S* unit | "/" S* NUMBER ] ]*; > + product : unit [ S* [ "*" S* unit | "/" S* unit ] ]*; > > In section 8.1.2 (type checking), replace the second two bullet points > in the list with the following: > > * At '*', apply these rules in order: > > 1. If both sides are <integer>, resolve to <integer>. > 2. If one side is <number> and the other is <number> or <integer>, > resolve to <number>. > 3. If one side is <number> or <integer> and the other is a > _dimension_, resolve to the type of the _dimension_. > 4. If one side is <time> and the other is <frequency>, resolve to > <number>. > 5. If one side is <length> and the other is <resolution>, resolve > to <number>. > 6. All other combinations of units are invalid. > > * At '/', apply these rules in order: > > 1. If both sides have the same type, resolve to <number>. > 2. If the left side is a <number> or <integer> and the right side is > also a <number> or <integer>, resolve to <number>. > 3. If the left side is a _dimension_ and the right side is <number> > or <integer>, resolve to the type of the _dimension_. > 4. If the left side is a <number> or <integer> and the right side > is a <length>, resolve to <resolution>. > 5. If the left side is a <number> or <integer> and the right side > is a <time>, resolve to <frequency>. > 6. All other combinations of units are invalid. So this does require you to manually keep the units singular, right? You're not allowed to write "calc(1px * 2px / 3px)", because due to order-of-operations you'll first evaluate the multiplication and hit clause 6. You'd have to reorder to "calc(1px / 3px * 2px)" or add parens to "calc(1px * (2px / 3px))" to produce a valid expression, right? I'm okay with this, as it keeps the implementation much simpler, just making sure that's intended. > Also, replace from "Also, division by zero is invalid" through the end > of that paragraph with: > > ... The expression is also invalid if it contains a division by > zero which can be detected at parse time. For example, > `calc(10px/0)` and `calc(10px/(1em - 1em))` are both invalid. > However, `calc(10px/1em)` and `calc(10px/5%)` are *not* invalid, > even though `1em` might evaluate to zero when the value is > computed, and `5%` might evaluate to zero when the value is used. > > In section 8.1.3 (computed value), delete the note about the > representation of a computed calc(), and perhaps also add some more > examples. > > In section 8.1.4 (range checking), add immediately after "...to the > range allowed in the target context": > > If a (sub-)expression contains a division by zero which was not > detected at parse time, the value of that (sub-)expression is > infinite. The result of any further computation on infinite > values is also infinite, except that dividing any finite value > by an infinite value produces zero. > > If the value resulting from a complete `calc()` expression is > infinite, it is clamped and becomes the most positive value > allowed in the target context. > > | NOTE: This deliberately differs from the behavior specified in IEEE > | 754 in order to avoid introducing NaNs and negative zero into CSS, > | However, implementations using IEEE 754-conformant floating point > | arithmetic internally can produce the above semantics by treating > | -Inf, +Inf, and NaN as "infinite", and -0 as equivalent to +0. This "most positive value" will be implementation-defined in most cases, as very few value contexts actually have an upper cap. Is that acceptable? ~TJ

Received on Thursday, 10 April 2014 21:21:02 UTC