This matches the hyphen-separated style of other files and directories in spec/.
13 KiB
More Math Functions: Draft 2.2
This proposal adds the following members to the built-in sass:math
module.
Table of Contents
Background
This section is non-normative.
Sass recently implemented a module system with a new built-in sass:math
module. The demand for built-in math functions can now be fulfilled safely by
implementing them inside this module. None of these new functions will be made
available on the global namespace.
Summary
This section is non-normative.
This proposal defines Sassified versions of all the mathematical functions in
the CSS Values and Units 4 Draft, as well as logarithms and the constants
e
and pi
. Each function is basically equivalent to its mathematical form,
with stricter unit handling. Proper unit handling prevents these functions from
creating meaningless units. For instance, consider (1px)^(1/3)
—what does
the unit px^(1/3)
mean?
To avoid issues like this, the exponential functions—log()
, pow()
, sqrt()
—
accept only a unitless number as input, and output a unitless number.
The trig functions—cos()
, sin()
, tan()
—accept a SassScript number with a
unit, as long as that unit is an angle type. If the input is a unitless
number, it is treated as though it were in rad
. These functions output a
unitless number.
The inverse trig functions—acos()
, asin()
, atan()
—accept a unitless number
and output a SassScript number in deg
. atan2()
is similar, but it accepts
two unitless numbers.
clamp()
accepts three SassScript numbers with compatible units: the
minimum value, preferred value, and maximum value. This function "clamps" the
preferred value in between the minimum and maximum values, while preserving
their units appropriately. For example, clamp(1in, 15cm, 12in)
outputs 15cm
,
whereas clamp(1in, 1cm, 12in)
outputs 1in
.
hypot()
accepts n
SassScript numbers with compatible units, and outputs the
length of the n
-dimensional vector that has components equal to each of the
inputs. Since the inputs' units may all be different, the output takes the unit
of the first input.
Semantics
Built-in Module Variables
Variables defined in built-in modules are not modifiable. As such, this proposal modifies the semantics of Executing a Variable Declaration within the Variables spec to read as follows:
To execute a VariableDeclaration
declaration
:
-
Let
value
be the result of evaluatingdeclaration
'sExpression
. -
Let
name
bedeclaration
'sVariable
. -
Let
resolved
be the result of resolving a variable namedname
.
-
If
name
is aNamespacedVariable
anddeclaration
has a!global
flag, throw an error. -
Otherwise, if
resolved
is a variable from a built-in module, throw an error. -
Otherwise, if
declaration
is outside of any block of statements, ordeclaration
has a!global
flag, orname
is aNamespacedVariable
:Letresolved
be the result of resolving a variable namedname
usingfile
,uses
, andimport
.
(...)
-
Otherwise, if
declaration
is within one or more blocks associated with@if
,@each
,@for
, and/or@while
rules and no other blocks:Letresolved
be the result of resolving a variable namedname
.
(...)
-
Otherwise, if no block containingdeclaration
has a scope with a variable namedname
, set the innermost block's scope's variablename
tovalue
.
-
Otherwise, if
resolved
is null, get the innermost block containingdeclaration
and set its scope's variablename
tovalue
. -
Otherwise, letscope
be the scope of the innermost block such thatscope
already has a variable namedname
. -
Otherwise, set
resolved
's value tovalue
.
Variables
$e
Equal to the value of the mathematical constant e
with a precision of 10
digits after the decimal point: 2.7182818285
.
$pi
Equal to the value of the mathematical constant pi
with a precision of 10
digits after the decimal point: 3.1415926536
.
Functions
clamp()
clamp($min, $number, $max)
- If the units of
$min
,$number
, and$max
are not compatible with each other, throw an error. - If some arguments have units and some do not, throw an error.
- If
$min >= $max
, return$min
. - If
$number <= $min
, return$min
. - If
$number >= $max
, return$max
. - Return
$number
.
hypot()
hypot($numbers...)
- If all numbers are not compatible with each other, throw an error.
- If some numbers have units and some do not, throw an error.
- If all numbers are unitless, the return value is unitless.
- Otherwise, the return value takes the unit of the leftmost number.
- If any number equals
Infinity
or-Infinity
, returnInfinity
. - Return the square root of the sum of the squares of each number.
Exponentiation
log()
log($number, $base: null)
- If
$number
has units, throw an error. - If
$base
is null:- If
$number < 0
, returnNaN
as a unitless number. - If
$number == 0
, return-Infinity
as a unitless number. - If
$number == Infinity
, returnInfinity
as a unitless number. - Return the natural log of
$number
, as a unitless number.
- If
- Otherwise, return the natural log of
$number
divided by the natural log of$base
, as a unitless number.
pow()
pow($base, $exponent)
-
If
$base
or$exponent
has units, throw an error. -
If
$exponent == 0
, return1
as a unitless number. -
Otherwise, if
$exponent == Infinity
or$exponent == -Infinity
:- If
$base == 1
or$base == -1
, returnNaN
as a unitless number. - If
$base < -1
or$base > 1
and if$exponent > 0
, or if$base > -1
and$base < 1
and$exponent < 0
, returnInfinity
as a unitless number. - Return
0
as a unitless number.
- If
-
Otherwise:
-
If
$base < 0
and$exponent
is not an integer, returnNaN
as a unitless number. -
If
$base == 0
and$exponent < 0
, or if$base == Infinity
and$exponent > 0
, returnInfinity
as a unitless number. -
If
$base == -0
and$exponent < 0
, or if$base == -Infinity
and$exponent > 0
:- If
$exponent
is an odd integer, return-Infinity
as a unitless number. - Return
Infinity
as a unitless number.
- If
-
If
$base == 0
and$exponent > 0
, or if$base == Infinity
and$exponent < 0
, return0
as a unitless number. -
If
$base == -0
and$exponent > 0
, or if$base == -Infinity
and$exponent < 0
:- If
$exponent
is an odd integer, return-0
as a unitless number. - Return
0
as a unitless number.
- If
-
Return
$base
raised to the power of$exponent
, as a unitless number.
-
sqrt()
sqrt($number)
- If
$number
has units, throw an error. - If
$number < 0
, returnNaN
as a unitless number. - If
$number == -0
, return-0
as a unitless number. - If
$number == 0
, return0
as a unitless number. - If
$number == Infinity
, returnInfinity
as a unitless number. - Return the square root of
$number
, as a unitless number.
Trigonometry
cos()
cos($number)
- If
$number
has units but is not an angle, throw an error. - If
$number
is unitless, treat it as though its unit wererad
. - If
$number == Infinity
or$number == -Infinity
, returnNaN
as a unitless number. - Return the cosine of
$number
, as a unitless number.
sin()
sin($number)
- If
$number
has units but is not an angle, throw an error. - If
$number
is unitless, treat it as though its unit wererad
. - If
$number == Infinity
or$number == -Infinity
, returnNaN
as a unitless number. - If
$number == -0
, return-0
as a unitless number. - If
$number == 0
, return0
as a unitless number. - Return the sine of
$number
, as a unitless number.
tan()
tan($number)
- If
$number
has units but is not an angle, throw an error. - If
$number
is unitless, treat it as though its unit wererad
. - If
$number == Infinity
or$number == -Infinity
, returnNaN
as a unitless number. - If
$number == -0
, return-0
as a unitless number. - If
$number == 0
, return0
as a unitless number. - If
$number
is equivalent to90deg +/- 360deg * n
, wheren
is any integer, returnInfinity
as a unitless number. - If
$number
is equivalent to-90deg +/- 360deg * n
, wheren
is any integer, return-Infinity
as a unitless number. - Return the tangent of
$number
, as a unitless number.
acos()
acos($number)
- If
$number
has units, throw an error. - If
$number < -1
or$number > 1
, returnNaN
as a number indeg
. - If
$number == 1
, return0deg
. - Return the arccosine of
$number
, as a number indeg
.
asin()
asin($number)
- If
$number
has units, throw an error. - If
$number < -1
or$number > 1
, returnNaN
as a number indeg
. - If
$number == -0
, return-0deg
. - If
$number == 0
, return0deg
. - Return the arcsine of
$number
, as a number indeg
.
atan()
atan($number)
- If
$number
has units, throw an error. - If
$number == -0
, return-0deg
. - If
$number == 0
, return0deg
. - If
$number == -Infinity
, return-90deg
. - If
$number == Infinity
, return90deg
. - Return the arctangent of
$number
, as a number indeg
.
atan2()
atan2($y, $x)
is distinct fromatan($y / $x)
because it preserves the quadrant of the point in question. For example,atan2(1, -1)
corresponds to the point(-1, 1)
and returns135deg
. In contrast,atan(1 / -1)
andatan(-1 / 1)
resolve first toatan(-1)
, so both return-45deg
.
atan2($y, $x)
- If
$y
and$x
are not compatible, throw an error. - If
$y
has units and$x
does not, or vice-versa, throw an error. - If the inputs match one of the following edge cases, return the provided
number. Otherwise, return the 2-argument arctangent of
$y
and$x
, as a number indeg
.
Edge cases
X | |||||||
---|---|---|---|---|---|---|---|
−Infinity | -finite | -0 | 0 | finite | Infinity | ||
Y | −Infinity | -135deg | -90deg | -90deg | -90deg | -90deg | -45deg |
-finite | -180deg | -90deg | -90deg | -0deg | |||
-0 | -180deg | -180deg | -180deg | -0deg | -0deg | -0deg | |
0 | 180deg | 180deg | 180deg | 0deg | 0deg | 0deg | |
finite | 180deg | 90deg | 90deg | 0deg | |||
Infinity | 135deg | 90deg | 90deg | 90deg | 90deg | 45deg |