如果你深入地使用过 Sass,那么一定会接触过 mixin。一个独立的 mixin 往往聚合了大量的控制指令来实现复杂的功能。
在本文中我们就将这些控制指令和表达式做一些讲解和实践。也许你在开发中不见得会用到它们,但是熟悉一下这些指令,可能会有意想不到的收获!
if()
if()
是 Sass 的一个内建函数,与之相似的 @if
则是一个内建指令。if()
用来做条件判断并返回特定值,示例如下:
@mixin test($condition) {
$color: if($condition, blue, red);
color:$color
}
.firstClass {
@include test(true);
}
.secondClass {
@include test(false);
}
编译结果:
.firstClass {
color: blue;
}
.secondClass {
color: red;
}
在上例中,if()
函数内的三个参数分别代表:测试条件,测试成功返回值,测试失败返回值(除了 false
和 null
之外的所有测试条件都被视为测试成功)。如果使用数字作为上述示例的条件,同样会返回测试成功的值:
.firstClass {
@include test(1);
}
@if
@if
后跟一个表达式,如果表达式的结果为 true
,则返回特定的样式,示例如下:
@mixin txt($weight) {
color: white;
@if $weight == bold { font-weight: bold;}
}
.txt1 {
@include txt(none);
}
.txt2 {
@include txt(bold);
}
编译结果:
.txt1 {
color: white;
}
.txt2 {
color: white;
font-weight: bold;
}
此外,我们可以使用 @if ... @else if ... @else
结构来处理多个条件,示例如下:
@mixin txt($weight) {
color: white;
@if $weight == bold { font-weight: bold;}
@else if $weight == light { font-weight: 100;}
@else if $weight == heavy { font-weight: 900;}
@else { font-weight: normal;}
}
.txt1 {
@include txt(bold);
}
.txt2 {
@include txt(light);
}
.txt3 {
@include txt(heavy);
}
.txt4 {
@include txt(none);
}
.txt5 {
@include txt(normal)
}
编译结果:
.txt1 {
color: white;
font-weight: bold;
}
.txt2 {
color: white;
font-weight: 100;
}
.txt3 {
color: white;
font-weight: 900;
}
.txt4 {
color: white;
font-weight: normal;
}
.txt5 {
color: white;
font-weight: normal;
}
这里的 .txt4
和 .txt5
是用来向各位演示 @if
的解析机制。在 .txt1
中,如果不传入 bold
,那么就不会生成 font-weight
相关的样式。
@for
@for
指令常用于循环输出。@for
有两种使用方式:from start through end
和 from start to end
,两者的区别在于,前者遍历的范围是 [start, end]
, 而后者的遍历范围是 [start, end]
。在 @for
循环中使用一个固定变量来替代遍历到的元素。如果你想实现从大到小的遍历,只需让 start
大于 end
即可。下面是 @for
的一个简单示例:
@for $i from 1 through 4 {
.col-#{$i} { width: 100/4 * $i + %;}
}
使用上面的这个例子,我们可以创建一套简单的栅格系统,编译结果如下:
.col-1 {
width: 25%;
}
.col-2 {
width: 50%;
}
.col-3 {
width: 75%;
}
.col-4 {
width: 100%;
}
从上面的示例中,我们综合了 Sass 的循环、变量、计算等多重功能。
@each
@each
指令同样可以用于循环输出,和 @for
的差别在于,@each
通过遍历 list
或者 map
实现循环输出:
@each $usr in bob, john, bill, mike {
.#{$usr}-avatar {
background-image: url('/img/#{$usr}.png');
}
}
@each
后面的 $usr
变量用于保存每次遍历到的元素,然后使用差值语法(#{var}
)来拼接正确的图片路径,编译结果如下:
.bob-avatar {
background-image: url("/img/bob.png");
}
.john-avatar {
background-image: url("/img/john.png");
}
.bill-avatar {
background-image: url("/img/bill.png");
}
.mike-avatar {
background-image: url("/img/mike.png");
}
如果遍历的对象是一个 map
,那么我们就可以使用两个变量来存储元素的 key
和 value
,示例如下:
$ppl: ( usr1:bob, usr2:john, usr3:bill, usr4:mike );
@each $key, $usr in $ppl {
.#{$usr}-avatar {
background-image: url('/img/#{$usr}.png');
}
}
此外,针对多个列表的遍历,我们也可以使用多个参数来保存相应的元素:
$alt: alert, yellow, red;
$sub: submit, white, green;
$bck: back, blue, transparent;
@each $type, $txt, $back in $alt,$sub,$bck {
.#{$type}-button {
color: $txt;
background-color: $back;
}
}
编译结果如下:
.alert-button {
color: yellow;
background-color: red;
}
.submit-button {
color: white;
background-color: green;
}
.back-button {
color: blue;
background-color: transparent;
}
@while
@while
指令也可以用于循环输出,它后面跟一个表达式,如果表达式结果为 false
,则停止循环体。下面使用 @while
来重写上述的 @for
示例:
$x:1;
@while $x < 13 {
.col-#{$x} { width: 100/12 * $x;}
$x: $x + 1;
};
在上面的示例中,我们用一个表达式来控制 @while
指令的执行,表达式中有一个变量 $x
,该变量一方面用于插值计算,另一方面在循环体内执行累加,最终当 $x < 13
的结果为 false
时,程序就会推出 @while
循环。
总结
Sass 的诸多特性让前端开发变得无比轻松,虽然 Sass 中的指令很强大,但是如果不是构建一个大象框架,往往并不能感觉到其中的美妙。随着对 Sass 的了解越来越深入,总有一天你会用到这些指令的 ^_^。
本文根据@Reggie Dawson的《Sass Basics: Control Directives and Expressions》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.sitepoint.com/sass-basics-control-directives-expressions/。
如需转载,烦请注明出处:http://www.w3cplus.com/preprocessor/sass-basics-control-directives-expressions.html