This proposal adds the following members to the built-in sass:math module.
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.
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.
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
valuebe the result of evaluatingdeclaration'sExpression. -
Let
namebedeclaration'sVariable. -
Let
resolvedbe the result of resolving a variable namedname.
-
If
nameis aNamespacedVariableanddeclarationhas a!globalflag, throw an error. -
Otherwise, if
resolvedis a variable from a built-in module, throw an error. -
Otherwise, if
declarationis outside of any block of statements, ordeclarationhas a!globalflag, ornameis aNamespacedVariable:Letresolvedbe the result of resolving a variable namednameusingfile,uses, andimport.
(...)
-
Otherwise, if
declarationis within one or more blocks associated with@if,@each,@for, and/or@whilerules and no other blocks:Letresolvedbe the result of resolving a variable namedname.
(...)
-
Otherwise, if no block containingdeclarationhas a scope with a variable namedname, set the innermost block's scope's variablenametovalue.
-
Otherwise, if
resolvedis null, get the innermost block containingdeclarationand set its scope's variablenametovalue. -
Otherwise, letscopebe the scope of the innermost block such thatscopealready has a variable namedname. -
Otherwise, set
resolved's value tovalue.
Equal to the value of the mathematical constant e with a precision of 10
digits after the decimal point: 2.7182818285.
Equal to the value of the mathematical constant pi with a precision of 10
digits after the decimal point: 3.1415926536.
clamp($min, $number, $max)
- If the units of
$min,$number, and$maxare 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($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
Infinityor-Infinity, returnInfinity. - Return the square root of the sum of the squares of each number.
log($number, $base: null)
- If
$numberhas units, throw an error. - If
$baseis null:- If
$number < 0, returnNaNas a unitless number. - If
$number == 0, return-Infinityas a unitless number. - If
$number == Infinity, returnInfinityas a unitless number. - Return the natural log of
$number, as a unitless number.
- If
- Otherwise, return the natural log of
$numberdivided by the natural log of$base, as a unitless number.
pow($base, $exponent)
-
If
$baseor$exponenthas units, throw an error. -
If
$exponent == 0, return1as a unitless number. -
Otherwise, if
$exponent == Infinityor$exponent == -Infinity:- If
$base == 1or$base == -1, returnNaNas a unitless number. - If
$base < -1or$base > 1and if$exponent > 0, or if$base > -1and$base < 1and$exponent < 0, returnInfinityas a unitless number. - Return
0as a unitless number.
- If
-
Otherwise:
-
If
$base < 0and$exponentis not an integer, returnNaNas a unitless number. -
If
$base == 0and$exponent < 0, or if$base == Infinityand$exponent > 0, returnInfinityas a unitless number. -
If
$base == -0and$exponent < 0, or if$base == -Infinityand$exponent > 0:- If
$exponentis an odd integer, return-Infinityas a unitless number. - Return
Infinityas a unitless number.
- If
-
If
$base == 0and$exponent > 0, or if$base == Infinityand$exponent < 0, return0as a unitless number. -
If
$base == -0and$exponent > 0, or if$base == -Infinityand$exponent < 0:- If
$exponentis an odd integer, return-0as a unitless number. - Return
0as a unitless number.
- If
-
Return
$baseraised to the power of$exponent, as a unitless number.
-
sqrt($number)
- If
$numberhas units, throw an error. - If
$number < 0, returnNaNas a unitless number. - If
$number == -0, return-0as a unitless number. - If
$number == 0, return0as a unitless number. - If
$number == Infinity, returnInfinityas a unitless number. - Return the square root of
$number, as a unitless number.
cos($number)
- If
$numberhas units but is not an angle, throw an error. - If
$numberis unitless, treat it as though its unit wererad. - If
$number == Infinityor$number == -Infinity, returnNaNas a unitless number. - Return the cosine of
$number, as a unitless number.
sin($number)
- If
$numberhas units but is not an angle, throw an error. - If
$numberis unitless, treat it as though its unit wererad. - If
$number == Infinityor$number == -Infinity, returnNaNas a unitless number. - If
$number == -0, return-0as a unitless number. - If
$number == 0, return0as a unitless number. - Return the sine of
$number, as a unitless number.
tan($number)
- If
$numberhas units but is not an angle, throw an error. - If
$numberis unitless, treat it as though its unit wererad. - If
$number == Infinityor$number == -Infinity, returnNaNas a unitless number. - If
$number == -0, return-0as a unitless number. - If
$number == 0, return0as a unitless number. - If
$numberis equivalent to90deg +/- 360deg * n, wherenis any integer, returnInfinityas a unitless number. - If
$numberis equivalent to-90deg +/- 360deg * n, wherenis any integer, return-Infinityas a unitless number. - Return the tangent of
$number, as a unitless number.
acos($number)
- If
$numberhas units, throw an error. - If
$number < -1or$number > 1, returnNaNas a number indeg. - If
$number == 1, return0deg. - Return the arccosine of
$number, as a number indeg.
asin($number)
- If
$numberhas units, throw an error. - If
$number < -1or$number > 1, returnNaNas a number indeg. - If
$number == -0, return-0deg. - If
$number == 0, return0deg. - Return the arcsine of
$number, as a number indeg.
atan($number)
- If
$numberhas 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($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
$yand$xare not compatible, throw an error. - If
$yhas units and$xdoes 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
$yand$x, as a number indeg.
| 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 | |