尽管Sass对算术很有帮助,但Sass在数学助手功能上却有些不足。 官方资料库中有一个公开问题 ,要求使用更多与数学相关的功能将近3年。
一些第三方供应商,例如Compass或SassyMath,提供了对数学功能的高级支持,但它们是外部依赖关系,可以(应该避免)。
关于此问题的最流行的要求之一是幂函数,甚至是指数运算符 。 不幸的是,Sass对此尚无任何支持,尽管仍在积极讨论中,但不太可能很快发生。
同时,能够将数字提高到一定程度在CSS中非常有用。 以下是一些可以派上用场的示例:
- 确定颜色的亮度 ;
- 将数字固定为一定的数字 ;
- 做一些( 反 ) 三角函数 ...
Sass实现
对我们来说幸运的是,有可能(而且非常简单)创建仅次于Sass的幂函数。 我们需要的只是一个循环和一些基本的数学运算符(例如*
和/
)。
正整数指数
我们函数的最小形式(称为pow
)看起来像这样:
@function pow($number, $exponent) {
$value: 1;
@if $exponent > 0 {
@for $i from 1 through $exponent {
$value: $value * $number;
}
}
@return $value;
}
这是一个例子:
.foo {
width: pow(20, 2) * 1px; // 400px
}
正整数或负整数
但是,它只能与正的$ power参数一起使用。 允许使用负指数并不难,我们只需要一个小的附加条件即可:
@function pow($number, $exponent) {
$value: 1;
@if $exponent > 0 {
@for $i from 1 through $exponent {
$value: $value * $number;
}
} @else if $exponent < 0 {
@for $i from 1 through -$exponent {
$value: $value / $number;
}
}
@return $value;
}
这是一个例子:
.foo {
width: pow(10, -2) * 1px; // 0.0001px
}
正或负指数
现在,如果我们需要非整数指数怎么办? 比如4.2
? 事实是,这确实不容易。 它仍然是可行的,但它不仅需要循环和一些操作。
为了在框架中完成modular-scale(..)
功能,尽管已在Bourbon存储库中完成了此操作(尽管已被拒绝)。 这是代码:
@function pow($number, $exponent) {
@if (round($exponent) != $exponent) {
@return exp($exponent * ln($number));
}
$value: 1;
@if $exponent > 0 {
@for $i from 1 through $exponent {
$value: $value * $number;
}
} @else if $exponent < 0 {
@for $i from 1 through -$exponent {
$value: $value / $number;
}
}
@return $value;
}
@function factorial($value) {
$result: 1;
@if $value == 0 {
@return $result;
}
@for $index from 1 through $value {
$result: $result * $index;
}
@return $result;
}
@function summation($iteratee, $input, $initial: 0, $limit: 100) {
$sum: 0;
@for $index from $initial to $limit {
$sum: $sum + call($iteratee, $input, $index);
}
@return $sum;
}
@function exp-maclaurin($x, $n) {
@return (pow($x, $n) / factorial($n));
}
@function exp($value) {
@return summation('exp-maclaurin', $value, 0, 100);
}
@function ln-maclaurin($x, $n) {
@return (pow(-1, $n + 1) / $n) * (pow($x - 1, $n));
}
@function ln($value) {
$ten-exp: 1;
$ln-ten: 2.30258509;
@while ($value > pow(10, $ten-exp)) {
$ten-exp: $ten-exp + 1;
}
@return summation(ln-maclaurin, $value / pow(10, $ten-exp), 1, 100) + $ten-exp * $ln-ten;
}
进一步的考虑
好吧,那很激烈。 如果您碰巧需要非整数指数的支持(例如4.2
),我建议您使用一个提供它的外部依赖项(例如sass-math-pow ),而不要在项目中包括所有这些代码。 并不是说这本身就是一件坏事,但托管如此大量的未经授权的polyfilling代码(托管包管理器)的原因并不是您的项目真正的角色。
还要注意,对于像Sass这样的薄层,所有这些操作都非常密集。 在这一点上,如果您的设计依赖于高级数学函数,则最好通过插件系统(Eyeglass,Ruby)将这些帮助程序的实现从上层(Node.js,Ruby等)传递到Sass。宝石等)。
但是对于基本的pow(..)
用法,我不能推荐足够简单的版本!