Skip to content

Commit ea66912

Browse files
committed
[css-values-4] First pass at specifying unit algebra, in terms of the TypedOM algorithms.
1 parent 99928ab commit ea66912

File tree

1 file changed

+65
-48
lines changed

1 file changed

+65
-48
lines changed

css-values-4/Overview.bs

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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>&lt;calc-sum></dfn> = <<calc-product>> [ [ '+' | '-' ] <<calc-product>> ]*
1689-
<dfn>&lt;calc-product></dfn> = <<calc-value>> [ '*' <<calc-value>> | '/' <<calc-number-value>> ]*
1684+
<dfn>&lt;calc-product></dfn> = <<calc-value>> [ [ '*' | '/' ] <<calc-value>> ]*
16901685
<dfn>&lt;calc-value></dfn> = <<number>> | <<dimension>> | <<percentage>> | ( <<calc-sum>> )
1691-
<dfn>&lt;calc-number-sum></dfn> = <<calc-number-product>> [ [ '+' | '-' ] <<calc-number-product>> ]*
1692-
<dfn>&lt;calc-number-product></dfn> = <<calc-number-value>> [ '*' <<calc-number-value>> | '/' <<calc-number-value>> ]*
1693-
<dfn>&lt;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

Comments
 (0)