剑客
关注科技互联网

如何编写自定义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/

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址