8. 控制指令 (Control Directives)

SassScript 提供了一些基础的控制指令,比如在满足一定条件时引用样式,或者设定范围重复输出格式。控制指令是一种高级功能,日常编写过程中并不常用到,主要与混合指令 (mixin) 配合使用,尤其是用在 Compass 等样式库中。

8.1. if()

The built-in if() function allows you to branch on a condition and returns only one of two possible outcomes. It can be used in any script context. The if function only evaluates the argument corresponding to the one that it will return – this allows you to refer to variables that may not be defined or to have calculations that would otherwise cause an error (E.g. divide by zero).

8.2. @if

@if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:

  1. p {
  2. @if 1 + 1 == 2 { border: 1px solid; }
  3. @if 5 < 3 { border: 2px dotted; }
  4. @if null { border: 3px double; }
  5. }

编译为

  1. p {
  2. border: 1px solid; }

@if 声明后面可以跟多个 @else if 声明,或者一个 @else 声明。如果 @if 声明失败,Sass 将逐条执行 @else if 声明,如果全部失败,最后执行 @else 声明,例如:

  1. $type: monster;
  2. p {
  3. @if $type == ocean {
  4. color: blue;
  5. } @else if $type == matador {
  6. color: red;
  7. } @else if $type == monster {
  8. color: green;
  9. } @else {
  10. color: black;
  11. }
  12. }

编译为

  1. p {
  2. color: green; }

8.3. @for

@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。这个指令包含两种格式:@for $var from <start> through <end>,或者 @for $var from <start> to <end>,区别在于 throughto 的含义:当使用 through 时,条件范围包含 <start><end> 的值,而使用 to 时条件范围只包含 <start> 的值不包含 <end> 的值。另外,$var 可以是任何变量,比如 $i<start><end> 必须是整数值。

  1. @for $i from 1 through 3 {
  2. .item-#{$i} { width: 2em * $i; }
  3. }

编译为

  1. .item-1 {
  2. width: 2em; }
  3. .item-2 {
  4. width: 4em; }
  5. .item-3 {
  6. width: 6em; }

8.4. @each

@each 指令的格式是 $var in <list>, $var 可以是任何变量名,比如 $length 或者 $name,而 <list> 是一连串的值,也就是值列表。

@each 将变量 $var 作用于值列表中的每一个项目,然后输出结果,例如:

  1. @each $animal in puma, sea-slug, egret, salamander {
  2. .#{$animal}-icon {
  3. background-image: url('/images/#{$animal}.png');
  4. }
  5. }

编译为

  1. .puma-icon {
  2. background-image: url('/images/puma.png'); }
  3. .sea-slug-icon {
  4. background-image: url('/images/sea-slug.png'); }
  5. .egret-icon {
  6. background-image: url('/images/egret.png'); }
  7. .salamander-icon {
  8. background-image: url('/images/salamander.png'); }

8.4.1 Multiple Assignment

The @each directive can also use multiple variables, as in @each $var1, $var2, … in . If is a list of lists, each element of the sub-lists is assigned to the respective variable. For example:

  1. @each $animal, $color, $cursor in (puma, black, default),
  2. (sea-slug, blue, pointer),
  3. (egret, white, move) {
  4. .#{$animal}-icon {
  5. background-image: url('/images/#{$animal}.png');
  6. border: 2px solid $color;
  7. cursor: $cursor;
  8. }
  9. }

is compiled to:

  1. .puma-icon {
  2. background-image: url('/images/puma.png');
  3. border: 2px solid black;
  4. cursor: default; }
  5. .sea-slug-icon {
  6. background-image: url('/images/sea-slug.png');
  7. border: 2px solid blue;
  8. cursor: pointer; }
  9. .egret-icon {
  10. background-image: url('/images/egret.png');
  11. border: 2px solid white;
  12. cursor: move; }

Since maps are treated as lists of pairs, multiple assignment works with them as well. For example:

  1. @each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  2. #{$header} {
  3. font-size: $size;
  4. }
  5. }

is compiled to:

  1. h1 {
  2. font-size: 2em; }
  3. h2 {
  4. font-size: 1.5em; }
  5. h3 {
  6. font-size: 1.2em; }

8.5. @while

@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。例如:

  1. $i: 6;
  2. @while $i > 0 {
  3. .item-#{$i} { width: 2em * $i; }
  4. $i: $i - 2;
  5. }
  1. .item-6 {
  2. width: 12em; }
  3. .item-4 {
  4. width: 8em; }
  5. .item-2 {
  6. width: 4em; }