@@ -1612,11 +1612,6 @@ Mathematical Expressions: ''calc()'', ''min()'', and ''max()''</h3>
16121612 or other expressions, such as ''attr()'' ,
16131613 that evaluate to a valid argument type (like <<length>> ).
16141614
1615- Issue: Per WG resolution, [=math functions=] will be extended to handle arbitrary unit algebra,
1616- like ''calc(1px / 1em)'' resolving to a <<number>> .
1617- This is already fully specified in [[css-typed-om]] ;
1618- it just needs to be converted over to raw CSS values for this spec.
1619-
16201615 <div class="example">
16211616 <pre>
16221617 section {
@@ -1686,11 +1681,8 @@ Syntax</h4>
16861681 <<min()>> = min( <<calc-sum>> # )
16871682 <<max()>> = max( <<calc-sum>> # )
16881683 <dfn><calc-sum></dfn> = <<calc-product>> [ [ '+' | '-' ] <<calc-product>> ]*
1689- <dfn><calc-product></dfn> = <<calc-value>> [ '*' <<calc-value>> | '/' <<calc-number -value>> ]*
1684+ <dfn><calc-product></dfn> = <<calc-value>> [ [ '*' | '/' ] <<calc-value>> ]*
16901685 <dfn><calc-value></dfn> = <<number>> | <<dimension>> | <<percentage>> | ( <<calc-sum>> )
1691- <dfn><calc-number-sum></dfn> = <<calc-number-product>> [ [ '+' | '-' ] <<calc-number-product>> ]*
1692- <dfn><calc-number-product></dfn> = <<calc-number-value>> [ '*' <<calc-number-value>> | '/' <<calc-number-value>> ]*
1693- <dfn><calc-number-value></dfn> = <<number>> | ( <<calc-number-sum>> )
16941686 </pre>
16951687
16961688 In addition, [=whitespace=]
@@ -1769,46 +1761,71 @@ Type Checking</h4>
17691761 <<number>> s never become "length-like" in ''calc()'' .
17701762 They always stay as <<number>> s.
17711763
1772- Operators form sub-expressions, which gain types based on their arguments.
1773- To make expressions simpler,
1774- operators have restrictions on the types they accept.
1775- At each operator,
1776- the types of the left and right argument are checked for these restrictions.
1777- If compatible, the type resolves as described below
1778- (the following ignores precedence rules on the operators for simplicity):
1779-
1780- <ul>
1781- <li>
1782- At ''+'' or ''-'' ,
1783- check that both sides have the same type,
1784- or that one side is a <<number>> and the other is an <<integer>> .
1785- If both sides are the same type,
1786- resolve to that type.
1787- If one side is a <<number>> and the other is an <<integer>> ,
1788- resolve to <<number>> .
1764+ <h5 id="type-checking-exprs">
1765+ Type-Checking Expressions</h5>
17891766
1790- <li>
1791- At ''*'' ,
1792- check that at least one side is <<number>> .
1793- If both sides are <<integer>> ,
1794- resolve to <<integer>> .
1795- Otherwise,
1796- resolve to the type of the other side.
1797-
1798- <li>
1799- At ''/'' ,
1800- check that the right side is <<number>> .
1801- If the left side is <<integer>> ,
1802- resolve to <<number>> .
1803- Otherwise,
1804- resolve to the type of the left side.
1805- </ul>
1806-
1807- If an operator does not pass the above checks, the expression is invalid.
1808- Also, division by zero is invalid. This includes both dividing by the
1809- literal number zero, as well as any numeric expression that evaluates to zero
1810- (as purely-numeric expressions can be evaluated without any additional
1811- information at parse time).
1767+ Operators form sub-expressions, which gain types based on their arguments.
1768+ In previous versions of this specification,
1769+ multiplication and division were limited in what arguments they could take,
1770+ to avoid producing more complex intermediate results
1771+ (such as ''1px * 1em'' , which is <<length>> ²)
1772+ and to make division-by-zero detectable at parse time.
1773+
1774+ This version now relaxes those restrictions,
1775+ allowing arbitrary expressions,
1776+ so long as the expression as a whole resolves to a singular unit
1777+ according to the following rules:
1778+
1779+ * At a ''+'' or ''-'' sub-expression,
1780+ attempt to [=add two types|add the types=] of the left and right arguments.
1781+ If this returns failure,
1782+ the entire [=math function=] is invalid.
1783+ Otherwise, the sub-expression's [=CSSNumericValue/type=] is the returned type.
1784+
1785+ * At a ''*'' or ''/'' sub-expression,
1786+ attempt to [=multiply two types|multiply the types=] of the left and right arguments.
1787+ If this returns failure,
1788+ the entire [=math function=] is invalid.
1789+ Otherwise, the sub-expression's [=CSSNumericValue/type=] is the returned type.
1790+
1791+ * The [=CSSNumericValue/type=] of a literal
1792+ is the result of [=creating a type=]
1793+ from the literal's unit,
1794+ if it's a <<dimension>> ,
1795+ or from "number"
1796+ if it's a <<number>> .
1797+ For <<percentage>> s,
1798+ if they're relative to another type
1799+ (as defined in the previous section),
1800+ their type is [=create a type|created=]
1801+ from the [=canonical unit=] of the type they're resolved to;
1802+ otherwise it's [=create a type|created=] from "percentage".
1803+
1804+ * The [=CSSNumericValue/type=] of a ''calc()'' expression
1805+ is the [=CSSNumericValue/type=] of its contained expression.
1806+ The [=CSSNumericValue/type=] of a ''min()'' or ''max()'' expression
1807+ is the result of [=adding two types|adding the types=]
1808+ of its comma-separated expressions.
1809+ If the result is failure,
1810+ the entire [=math function=] is invalid.
1811+
1812+ The [=math function=] resolves to <<length>> , <<angle>> , <<time>> , <<frequency>> , <<resolution>> , <<flex>> , or <<percentage>>
1813+ according to which of those productions its [=CSSNumericValue/type=] [=CSSNumericValue/matches=] .
1814+ (These categories are mutually exclusive.)
1815+ If it can't [=CSSNumericValue/match=] any of these,
1816+ the [=math function=] is invalid.
1817+
1818+ As a further breaking change from the previous version of this specification,
1819+ division by zero is now allowed.
1820+ Expressions must follow IEEE-754 semantics for recognition and propagation
1821+ of infinities and NaN values,
1822+ including tracking the difference between +0 and -0.
1823+ (However, CSS treats both zeroes as the same,
1824+ if a [=math function=] resolves to one of them.)
1825+ Infinities are, by definition, out-of-range for any property,
1826+ and trigger appropriate clamping at used-value time per [[#calc-range]] .
1827+ If a [=math function=] would resolve to NaN,
1828+ it instead resolves to positive infinity.
18121829
18131830 Note: Algebraic simplifications do not affect the validity of a [=math function=] or its resolved type.
18141831 For example, ''calc(5px - 5px + 10s)'' and ''calc(0 * 5px + 10s)'' are both invalid
0 commit comments