Skip to content

Commit 7d66305

Browse files
committed
[css-values-5] Move calc-size basis canonicalization to only occur when interpolating. w3c#10220
1 parent 8a60567 commit 7d66305

File tree

1 file changed

+79
-46
lines changed

1 file changed

+79
-46
lines changed

css-values-5/Overview.bs

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,17 +1736,14 @@ in a safe, well-defined way.
17361736
<pre class=prod>
17371737
<dfn function lt="calc-size()">&lt;calc-size()></dfn> = calc-size( <<calc-size-basis>>, <<calc-sum>> )
17381738
1739-
<dfn>&lt;calc-size-basis></dfn> = [ <<intrinsic-size-keyword>> | percentage | <<calc-size()>> | any | <<calc-sum>> ]
1739+
<dfn>&lt;calc-size-basis></dfn> = [ <<intrinsic-size-keyword>> | <<calc-size()>> | any | <<calc-sum>> ]
17401740
</pre>
17411741

17421742
The <dfn>&lt;intrinsic-size-keyword></dfn> production
17431743
matches any [=intrinsic size=] keywords allowed in the context.
17441744
For example, in 'width',
17451745
it matches ''width/auto'', ''width/min-content'', ''width/stretch'', etc.
17461746

1747-
The <dfn for=calc-size() value>percentage</dfn> basis keyword
1748-
indicates a basis size of ''100%''.
1749-
17501747
<details class=note>
17511748
<summary>Why can ''calc-size()'' be nested?</summary>
17521749

@@ -1761,8 +1758,9 @@ indicates a basis size of ''100%''.
17611758
or even just ''--foo: min-content'',
17621759
then ''calc( (var(--foo)) + 20px )'' fails.
17631760

1764-
The nesting is simplified away at computed-value time,
1765-
so the basis always ends up as a single keyword
1761+
The nesting is simplified away during interpolation,
1762+
and at used-value time,
1763+
so the basis always ends up as a simple value
17661764
by the time interpolation and other effects occur;
17671765
see [[#simplifying-calc-size]].
17681766
</details>
@@ -1840,30 +1838,51 @@ must explicitly include it in its grammar.
18401838
<h3 id=simplifying-calc-size>
18411839
Simplifying ''calc-size()''</h3>
18421840

1843-
At [=specified value=] time,
1844-
the [=calc-size calculation=] of a ''calc-size()''
1845-
is simplified to the extent possible,
1846-
similar to [=math functions=],
1847-
as defined in [[css-values-4#calc-simplification]]
1848-
1849-
At [=computed value=] time,
1850-
the [=calc-size calculation=] is again simplified to the extent possible.
1851-
In addition,
1852-
the [=calc-size basis=] is simplified in some cases:
1853-
1854-
* If the [=calc-size basis=] is a ''calc-size()'' function itself,
1855-
the [=calc-size basis=] of the outer function
1856-
is replaced with that of the inner function,
1857-
and the inner function's [=calc-size calculation=]
1858-
is [=substitute into a calc-size calculation|substituted=]
1859-
into the outer function's [=calc-size calculation=].
1860-
* If the [=calc-size basis=] is a <<length-percentage>>,
1861-
the [=calc-size basis=] is replaced with the keyword ''calc-size()/percentage''
1862-
and the <<length-percentage>> is [=de-percentify a calc-size calculation|de-percentified=],
1863-
then [=substitute into a calc-size calculation|substituted=]
1864-
into the [=calc-size calculation=].
1865-
1866-
(The above is performed recursively, if necessary.)
1841+
Similar to [=math functions=],
1842+
at both [=specified value=] and [=computed value=] times
1843+
the [=calc-size calculation=]
1844+
(and the [=calc-size basis=], if it's a <<calc-sum>>)
1845+
are simplified to the extent possible,
1846+
as defined in [[css-values-4#calc-simplification]].
1847+
1848+
<div algorithm>
1849+
To <dfn export for=calc-size()>canonicalize for interpolation</dfn>
1850+
a ''calc-size()'' function:
1851+
1852+
<dl class=switch>
1853+
: If the [=calc-size basis=] is a ''calc-size()'' function itself
1854+
:: The [=calc-size basis=] of the outer function
1855+
is replaced with that of the inner function,
1856+
and the inner function's [=calc-size calculation=]
1857+
is [=substitute into a calc-size calculation|substituted=]
1858+
into the outer function's [=calc-size calculation=].
1859+
1860+
: Otherwise, if the [=calc-size basis=] is a <<calc-sum>> whose
1861+
[=CSSNumericValue/type=] [=CSSNumericValue/matches=] <<length>>
1862+
(no percentage present)
1863+
:: Replace the basis with ''calc-size/any'',
1864+
and the original basis is [=substitute into a calc-size calculation|substituted=]
1865+
into the [=calc-size calculation=].
1866+
1867+
: Otherwise, if the [=calc-size basis=] is any other <<calc-sum>>
1868+
(contains a percentage)
1869+
:: Replace the basis with ''100%''
1870+
and the original basis is [=de-percentify a calc-size calculation|de-percentified=],
1871+
then [=substitute into a calc-size calculation|substituted=]
1872+
into the [=calc-size calculation=].
1873+
</dl>
1874+
1875+
(The above is performed recursively, if necessary.)
1876+
1877+
If any [=substitute into a calc-size calculation=]
1878+
returns failure,
1879+
the entire operation immediately returns failure.
1880+
1881+
Note: After canonicalization,
1882+
a ''calc-size()'' function
1883+
will only have a [=calc-size basis=] that's a keyword,
1884+
or the value ''100%''.
1885+
</div>
18671886

18681887
<details class=note>
18691888
<summary>Why are percentages simplified in this way?</summary>
@@ -1925,8 +1944,7 @@ the [=calc-size basis=] is simplified in some cases:
19251944

19261945
3. If this substitution would produce a value
19271946
larger than an UA-defined limit,
1928-
the property the subsitution is happening in
1929-
becomes [=invalid at computed-value time=].
1947+
return failure.
19301948

19311949
Note: This is intentionally identical
19321950
to the protection against substitution attacks
@@ -1941,8 +1959,8 @@ the [=calc-size basis=] is simplified in some cases:
19411959
Resolving ''calc-size()''</h3>
19421960

19431961
A ''calc-size()'' is treated, in all respects,
1944-
as if it were its [=calc-size basis=].
1945-
(With ''calc-size()/percentage'' acting like ''100%''.)
1962+
as if it were its [=calc-size basis=]
1963+
(with ''calc-size()/any'' acting as an unspecified [=definite=] size).
19461964

19471965
When actually performing layout calculations, however,
19481966
the size represented by its [=calc-size basis=]
@@ -1956,9 +1974,9 @@ equal to its [=calc-size calculation=].)
19561974

19571975
<div class=example>
19581976
For example,
1959-
an element with ''height: calc-size(auto, size + 20px)''
1977+
an element with ''height: calc-size(auto, round(up, size, 20px))''
19601978
will be treated identically to an element with ''height: auto'',
1961-
but will end up being 20px taller.
1979+
but with its size rounded up to the nearest multiple of ''20px''.
19621980
</div>
19631981

19641982
When evaluating the [=calc-size calculation=],
@@ -1971,9 +1989,8 @@ is treated differently;
19711989
[[#simplifying-calc-size|simplification]]
19721990
moves the percentage into the [=calc-size calculation=]
19731991
and replaces it with ''size'' references.
1974-
The [=calc-size basis=] then becomes ''calc-size()/percentage'',
1975-
which acts like percentages would normally in that context
1976-
regardless of definite-ness,
1992+
The [=calc-size basis=] then becomes ''100%'',
1993+
behaving as whatever ''100%'' would normally do in that context,
19771994
including possibly making a property [=behave as auto=], etc.)
19781995

19791996
<div class=note>
@@ -2001,16 +2018,21 @@ including possibly making a property [=behave as auto=], etc.)
20012018
Interpolating ''calc-size()''</h3>
20022019

20032020
Two ''calc-size()'' functions can be interpolated if
2004-
(after simplification):
2021+
(after being [=canonicalized for interpolation=]):
20052022

2006-
: both [=calc-size basises=] are the same <<intrinsic-size-keyword>>
2007-
:: The result's [=calc-size basis=] is that keyword
2023+
<dl class=switch>
2024+
: Either function returned failure from being [=canonicalized for interpolation=]
2025+
:: The values cannot be interpolated.
20082026

2009-
: either [=calc-size basis=] is ''calc-size()/any''
2010-
:: The result's [=calc-size basis=] is the non-''calc-size()/any'' basis
2011-
(or ''calc-size()/any'' if both are).
2027+
: Both [=calc-size basises=] are identical
2028+
:: The result's [=calc-size basis=] is the that basis value.
20122029

2013-
The result's [=calc-size calculation=] is the interpolation of the two input [=calc-size calculations=].
2030+
: Either [=calc-size basis=] is ''calc-size()/any''
2031+
:: The result's [=calc-size basis=] is the non-''calc-size()/any'' basis.
2032+
</dl>
2033+
2034+
The result's [=calc-size calculation=]
2035+
is the interpolation of the two input [=calc-size calculations=].
20142036

20152037
Note: These interpolation restrictions ensure that a ''calc-size()''
20162038
doesn't try to act in two different ways at once;
@@ -2061,6 +2083,17 @@ transitioning to/from ''calc-size(any, [=definite=] length)''
20612083
will <em>always</em> work smoothly,
20622084
regardless of how the other side of the transition is specified.
20632085

2086+
Note: This "upgrade a plain value into a ''calc-size()''" behavior
2087+
puts <<length-percentage>> values into the [=calc-size calculation=].
2088+
This allows values with percentages
2089+
to interpolate with intrinsic size keywords,
2090+
but does mean that when a percentage isn't [=definite=],
2091+
it'll resolve to zero.
2092+
If you want to resolve to the actual size the percentage would make the element,
2093+
explicitly write a ''calc-size()''
2094+
with the value in its [=calc-size basis=],
2095+
like ''calc-size(50%, size)''.
2096+
20642097
Issue: Or is it compatible to just allow direct interpolation
20652098
between keywords and fixed lengths,
20662099
even without an explicit ''calc-size()'' being used on one size?

0 commit comments

Comments
 (0)