>
with the return type [=made consistent=]
with the input [=calculation’s=] type.
The ''pow()'' function can be useful for strategies like
CSS Modular Scale,
which relates all the font-sizes on a page to each other by a fixed ratio.
These sizes can be easily written into custom properties like:
:root {
--h6: calc(1rem * pow(1.5, -1));
--h5: calc(1rem * pow(1.5, 0));
--h4: calc(1rem * pow(1.5, 1));
--h3: calc(1rem * pow(1.5, 2));
--h2: calc(1rem * pow(1.5, 3));
--h1: calc(1rem * pow(1.5, 4));
}
...rather than writing out the values in pre-calculated numbers like ''5.0625rem''
(what ''calc(1rem * pow(1.5, 4))'' resolves to)
which have less clear provenance when encountered in a stylesheet.
With a single argument,
''hypot()'' gives the absolute value of its input;
''hypot(2em)'' and ''hypot(-2em)'' both resolve to ''2em''.
With more arguments,
it gives the size of the main diagonal of a box
whose side lengths are given by the arguments.
This can be useful for transform-related things,
giving the distance that an element will actually travel
when it's translated by a particular X, Y, and Z amount.
For example, ''hypot(30px, 40px)'' resolves to ''50px'',
which is indeed the distance between an element's starting and ending positions
when it's translated by a ''translate(30px, 40px)'' transform.
If an author wanted elements to get smaller as they moved further away from their starting point
(drawing some sort of word cloud, for example),
they could then use this distance in their scaling factor calculations.
With a single argument,
''log()'' provides the “natural log” of its argument,
or the log base e,
same as JavaScript.
If one instead wants log base 10
(to, for example, count the number of digits in a value)
or log base 2
(counting the number of bits in a value),
''log(X, 10)'' or ''log(X, 2)'' provide those values.
Argument Ranges
In ''pow(A, B)'',
if A is negative and finite,
and B is finite,
B must be an integer,
or else the result is NaN.
If A or B are infinite or 0,
the following tables give the results:
| A is −∞
| A is 0⁻
| A is 0⁺
| A is +∞
|
B is −finite
| 0⁻ if B is an odd integer, 0⁺ otherwise
| −∞ if B is an odd integer, +∞ otherwise
| +∞
| 0⁺
|
B is 0
| always 1
|
B is +finite
| −∞ if B is an odd integer, +∞ otherwise
| 0⁻ if B is an odd integer, 0⁺ otherwise
| 0⁺
| +∞
|
| A is < -1
| A is -1
| -1 < A < 1
| A is 1
| A is > 1
|
B is +∞
| result is +∞
| result is NaN
| result is 0⁺
| result is NaN
| result is +∞
|
B is −∞
| result is 0⁺
| result is NaN
| result is +∞
| result is NaN
| result is 0⁺
|
In ''sqrt(A)'',
if A is +∞,
the result is +∞.
If A is 0⁻,
the result is 0⁻.
If A is less than 0,
the result is NaN.
In ''hypot(A, …)'',
if any of the inputs are infinite,
the result is +∞.
In ''log(A, B)'',
if B is 1 or negative,
B values between 0 and 1,
or greater than 1,
are valid.
the result is NaN.
If A is negative,
the result is NaN.
If A is 0⁺ or 0⁻,
the result is −∞.
If A is 1,
the result is 0⁺.
If A is +∞,
the result is +∞.
In ''exp(A)'',
if A is +∞,
the result is +∞.
If A is −∞,
the result is 0⁺.
(See [[#calc-type-checking]] for details on how [=math functions=] handle NaN and infinities.)
All of these behaviors are intended to match the "standard" definitions of these functions
as implemented by most programming languages,
in particular as implemented in JS.
The only divergences from the behavior of the equivalent JS functions
are that NaN is "infectious" in every function,
forcing the function to return NaN if any argument calculation is NaN.
Details of the JS Behavior
There are two cases in JS where a NaN is not "infectious"
to the math function it finds itself in:
* Math.hypot(Infinity, NaN)
will return Infinity
.
* Math.pow(NaN, 0)
will return 1
.
The logic appears to be that,
if you replace the NaN with any Number,
the return value will be the same.
However, this logic is not applied consistently to the Math
functions:
Math.max(Infinity, NaN)
returns NaN
, not Infinity
;
the same is true of Math.min(-Infinity, NaN)
.
Because this is an error corner case,
JS isn't consistent on the matter,
and NaN recognition/handling of [=calculations=]
is likely done at a higher CSS level
rather than in the internal math functions anyway,
consistency in CSS was chosen to be more important,
so all functions were defined to have "infectious" NaN.
Sign-Related Functions: ''abs()'', ''sign()''
The sign-related functions--
''abs()'' and ''sign()''--
compute various functions related to the sign of their argument.
The abs(A) function
contains one [=calculation=] A,
and returns the absolute value of A,
as the same [=CSSNumericValue/type=] as the input:
if A's numeric value is positive or 0⁺, just A again;
otherwise ''-1 * A''.
The sign(A) function
contains one [=calculation=] A,
and returns -1 if A's numeric value is negative,
+1 if A's numeric value is positive,
0⁺ if A's numeric value is 0⁺,
and 0⁻ if A's numeric value is 0⁻.
The return type is a <>,
[=made consistent=]
with the input [=calculation’s=] type.
Note: Both of these functions operate on the fully simplified/resolved form of their arguments,
which may give unintuitive results at first glance.
In particular,
an expression like ''10%'' might be positive or negative once it's resolved,
depending on what value it's resolved against.
For example, in 'background-position' positive percentages
resolve to a negative length,
and vice versa,
if the background image is larger than the background area.
Thus ''sign(10%)'' might return ''1'' or ''-1'',
depending on how the percentage is resolved!
(Or even ''0'', if it's resolved against a zero length.)
Numeric Keywords
Keywords in [=calculations=]
provide access to values that are difficult or impossible to represent as literals.
Each keyword defines its value,
its [=determine the type of a calculation|type=],
and when it can be resolved.
Numeric Constants: ''e'', ''pi''
While the trigonometric and exponential functions
handle many complex numeric operations,
some reasonable calculations must be put together more manually,
and many times these include well-known constants,
such as e and π.
Rather than require authors to manually type out
several digits of these constants,
a few of them are provided directly:
: e
:: the base of the natural logarithm,
approximately equal to 2.7182818284590452354.
: pi
:: the ratio of a circle's circumference to its diameter,
approximately equal to 3.1415926535897932.
Both of these keywords are <>s,
and resolve at parse time.
Note: These keywords are only usable within a calculation,
such as ''calc(pow(e, pi) - pi)'', or ''min(pi, 5, e)''.
If used outside of a calculation,
they're treated like any other keyword:
''animation-name: pi;'' refers to an animation named "pi";
''line-height: e;'' is invalid
(not similar to ''line-height: 2.7'',
but ''line-height: calc(e);'' is).
Degenerate Numeric Constants: ''infinity'', ''-infinity'', ''NaN''
When a [=calculation=] or a subtree of a [=calculation=]
becomes [=infinite=] or [=NaN=],
representing it with a numeric value is no longer possible.
To aid in serialization of these degenerate values,
the following additional math constants are defined:
: infinity
:: the value positive infinity (+∞)
: -infinity
:: the value negative infinity (−∞)
: NaN
:: the value NaN
All of these keywords are <>s,
and resolve at parse time.
As usual for CSS keywords,
these are [=ASCII case-insensitive=].
Thus, ''calc(InFiNiTy)'' is perfectly valid.
However, ''NaN'' must be serialized with this canonical casing.
Note: As these keywords are <>s,
to get an infinite length,
for example,
requires an expression like ''calc(infinity * 1px)''.
Note: These constants are defined mostly
to make serialization of infinite/NaN values simpler and more obvious,
but can be used to indicate a "largest possible value",
since an infinite value gets clamped to the allowed range.
It's rare for this to be reasonable,
but when it is,
using ''infinity'' is clearer in its intent
than just putting an enormous number in one's stylesheet.
Numeric Variables
Other specifications can define additional keywords
which are usable in [=calculations=]
in certain contexts.
For example, [=relative color=] syntax
defines a number of color-channel keywords
representing the value of each color channel as a <>.
Each specifications defining such keywords
must define for each keyword:
* its value
* its [=determine the type of a calculation|type=] (<>, <>, etc)
* when it resolves (parse time, computed-value time, or used-value time)
Syntax
The syntax of a [=math function=] is:
<> = calc( <> )
<> = min( <># )
<> = max( <># )
<> = clamp( [ <> | none ], <>, [ <> | none ] )
<> = round( <>?, <>, <>? )
<> = mod( <>, <> )
<> = rem( <>, <> )
<> = sin( <> )
<> = cos( <> )
<> = tan( <> )
<> = asin( <> )
<> = acos( <> )
<> = atan( <> )
<> = atan2( <>, <> )
<> = pow( <>, <> )
<> = sqrt( <> )
<> = hypot( <># )
<> = log( <>, <>? )
<> = exp( <> )
<