Sass的表达式和控制命令

如果你深入地使用过 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() 函数内的三个参数分别代表:测试条件,测试成功返回值,测试失败返回值(除了 falsenull 之外的所有测试条件都被视为测试成功)。如果使用数字作为上述示例的条件,同样会返回测试成功的值:

.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 endfrom start to end,两者的区别在于,前者遍历的范围是 [start, end], 而后者的遍历范围是 [start, end-1]。在 @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,那么我们就可以使用两个变量来存储元素的 keyvalue,示例如下:

$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