Sass的表达式和控制命令

英文原文:Sass Basics: Control Directives and Expressions
译者:南北
译文地址:
http://www.w3cplus.com/preprocessor/sass-basics-control-directives-expressions.html
如果你深入地使用过 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 end 和 from 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 中的指令很强大,但是如果不是构建一个大象框架,往往并不能感觉到其中的美妙。随着对 Sass 的了解越来越深入,总有一天你会用到这些指令的 _。

    推荐阅读