如何编写自定义Sass 函数

如果您构建过不少网站,可能已注意到可以在一个项目中轻易的复制代码然后跨项目应用。反复复制相同的代码会浪费时间和增加错误出现的可能性。

如果您构建过不少网站,可能已注意到可以在一个项目中轻易的复制代码然后跨项目应用。反复复制相同的代码会浪费时间和增加错误出现的可能性。在Sass之前的系列中,我曾说mixins是样式重用和 编写 DRYer代码

的一个选择。Functions是实现相同功能的另一个方法。

最近几个月我一直在讲Sass的 数据类型、运算符和函数

。我们讲过了

numbers

strings

colors

colors again

lists

lists again

, 和

maps

。过去几周我讲到了控制指令。今天是该系列的最后一部分,我想以 @function

指令和如何编写自定义函数结课。

如何创建和使用自定义函数

函数是可返回一个Sass任何数据类型单一值的代码块。创建自定义函数需要两个Sass指令, @function

@return

。前者创建函数,后者表明了函数将返回的值。

@function function-name($args) { 

@return value-to-be-returned;

}

传递到函数中的参数是可选的,尽管你会经常使用它们。通常Sass函数会使用传递过去的参数进行运算,也可能是一些所有函数都可以访问的 全局变量

由于历史原因,函数名可交替使用破折号或下划线,故 function-name

function_name

是相同的函数,可使用破折号或下划线调用函数,无论命名时使用的是哪个。

上述代码只显示了一行返回一个值的代码,但大多数函数所做的并不仅限于此,于是 @return

指令将会作为函数的最后一行。

记得只有一个值返回,这个值可以是任何的数据类型,返回的可以是数字 9

,字符串 "I am a string"

,或者一种数据结构,比如 list

map

,里面包含您想要的任何值。

要使用函数您需要提供函数名和参数,放在想要返回值显示的位置。

p { 

font-size: function-name($args);

}

p {

font-size: function_name($args);

}

重申,这两个都会调用同一个函数。可以假定该函数将计算 px

em

值,并返回作为

段落的 font-size

正像我所说的,函数可以访问任何全局定义的变量。下个示例中我创建了两个全局变量, $total

$col

$total

表示网格的总列数, $col

表示一个 3

列宽的 网格字段

$total: 8; 

$col: 3

@function column-width() {

@return percentage($col/$total);

}

这个函数没有任何参数。它用 $col

除以 $total

,使用内置 percentage

函数将结果在返回之前变成百分值。

我们可在想要返回值显示的位置通过添加函数名来调用函数。因为这个函数不带参数,调用时无需传参。

.col-3 { 

width: column-width();

}

函数完成运算后代码被编译为:

.col-3 { width: 37.5%; }

这样编写的函数用处不大,因为不得不硬编码总列数和 网格字段

的大小作为全局变量。一个更有用的方案是将这些变量当成参数传递,下面我们重写这个函数。

@function column-width($col, $total) { 

@return percentage($col/$total);

}

该函数现在接收参数,我们必须在函数调用期间传值过去,尽管我们可以重用这个函数并用不同的参数调用它。

.col-3 { 

width: column-width(3, 8);

}

.col-5 {

width: column-width(5, 8);

}

会编译成:

.col-3 { 

width: 37.5%;

}

.col-5 {

width: 62.5%;

}

关键字参数

您可能已经注意到,在前面的实例中,我按照它们在函数中列出的顺序传递参数。这是必须的,除非您使用关键字。

可以使用 key:value

的格式传递键/值对。

.col-3 {  

width: column-width($col: 3, $total: 8);

}

如果包含了键名,则不必按它们在函数中列出的顺序来排列。

.col-3 {  

width: column-width($total: 8, $col: 3);

}

尽管函数是以先 $col

$total

的顺序列出,通过使用每个值之前的关键字,函数知道哪个对应哪个。

您还可以在创建函数时声明参数的默认值。这里我修改了函数,所以总列数的默认值为 8

@function column-width($col, $total:8) {  

@return percentage($col/$total);

}

.col-3 {

width: column-width(3);

}

上面的代码只传递了一个值到函数。该函数会使用我没有传递的那个参数的默认值,仍然会编译成:

.col-3 {  

width: 37.5%;

}

您可通过传递带有或者不带关键字的参数来覆盖默认值。

.col-3 {  

width: column-width(3, 9);

}

.col-4 {

width: column-width($col:3, $total:12);

}

一个更实际的例子

到目前为止并没有哪个例子很实用。我写它们是为了解释某事物如何运作。下面我们来写一些更实用的代码。

这里我将全局变量 $total

设置为 8

,然后重写了前面例子中的函数,使用全局变量,而不是将总列数作为参数传递。

最后我使用了一个从 1

运行到 $total

值的 for

循环。在循环里面,计数器 $i

成为了类名的一部分,并且类的宽度是通过将$i的值传递给函数而生成的。

$total: 8;

@function column-width($col) {

@return percentage($col/$total);

}

@for $i from 1 through $total {

.col-#/{$i/} { width: column-width($i) };

}

Sass代码编译为:

.col-1 { width: 12.5%; }  

.col-2 { width: 25%; }

.col-3 { width: 37.5%; }

.col-4 { width: 50%; }

.col-5 { width: 62.5%; }

.col-6 { width: 75%; }

.col-7 { width: 87.5%; }

.col-8 { width: 100%; }

如果您决定使用 12

列或 9

列或 4

列而不是 8

列布局,您只需要更改 $total

的值。自定义函数和 @for

循环将完成其余操作。

可变参数

mixins

一样,函数可以通过在参数名称后面使用 3

个点(非省略号)来接收可变参数。该函数将从传递给它的变量参数创建一个列表。

在下面的示例中我创建了一个函数,它接收一个名为 $index

的参数和一个名为 $widths...

的变量参数。

@function column-width($index, $widths...){  

@return nth($widths, $index);

}

该函数将使用内置的 nth

函数找到 $widths

中下标为 $index

的值。当调用该函数时,我传递给它一个索引值和一系列的百分比宽度。

.col-3 {  

width: column-width(3, 25%, 50%, 75%, 100%);

}

因为 75%

是索引为 3

的值,所以代码编译为:

.col-3 {  

width: 75%;

}

坦白说这不是特别有用的函数,因为如果仅仅是设置宽度,不调用函数设置会更容易。虽然可变参数在mixins中有用,可以添加多个盒子阴影,但很难想象它们在函数中有什么用处。但这仍然是你可以做的事,我认为值得分享。

给您的函数名添加前缀

值得一提的是,给您的函数名添加一个前缀不失为一个好主意,这样可避免与内置函数或您可能正在使用的库产生命名冲突。

不难想象其他人创建了一个与我在示例中使用的函数名称冲突的 column-width

函数。将其命名为 vanseo-column-width

可能更好,因为第三方函数不太可能会使用相同的前缀。

Function还是Mixin

因为 Sass functions 和 Sass mixins

是相似的,您可能纳闷应该使用哪个。虽然类似,但它们有一个重要的区别,这表明了在什么时候使用哪个是最佳的。

两者之间的主要区别是,Sass代码的mixins输出行将直接编译为CSS样式,而函数则返回一个可以作为CSS属性或可传递给另一个function或mixin的值。

说实话,您可以将每个函数都改写为混合宏的形式,反之亦然,但每个都有清晰的用例。

想要直接输出样式,使用mixin;想执行返回值的运算,使用function。例如,确定响应容器的百分比宽度公式可能看起来很熟悉

target / context = result

因为这是一个可能在样式表中执行多次的运算,适合使用function,您可以传递target和context的值从而得到返回的结果。

总结

Functions是一种将可重用的代码移动到单独包的方法。它们与mixins相似,两者的不同点在于输出。 Functions

返回一个值而mixins输出代码。如果您知道怎么使用其中一个,那么使用另一个对您来说也不难。

Sass数据类型,运算符和函数系列已经到了尾声。希望在系列的最后您能理解我为什么花时间讲每种不同的数据类型。除颜色外,其他的数据类型在function和mixins中更有用。

本文根据 @Steven Bradley

的《 How To Write Your Own Custom Sass Functions

》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://vanseodesign.com/css/custom-sass-functions/

未登录用户
全部评论0
到底啦