Sass の if 関数

これは CSS Preprocessor Advent Calendar 2012 の 5 日目の記事です。

今日はあまり知られていない Sass の if 関数について紹介したいと思います。

Sass には、条件分岐のための制御構文として @if ディレクティブ(いわゆる if 文)が用意されています。

$type: ocean;

p {
  @if $type == ocean {
    color: blue;
  } @else {
    color: black;
  }
}

Sass の紹介記事の中では必ずと言っていいほど出てきますし、皆さんも一度は使ったことがあるのではないでしょうか。

実はこの @if ディレクティブ以外に、Sass には if 関数が標準で用意されています。

上のコードを if 関数を使って書き直すと、次のようになります。

$type: ocean;

p {
  color: if($type == ocean, blue, black);
}

1 行で非常に簡潔に書くことができました。🙂

@if ディレクティブとの一番の違いは、値でしか利用できない点です。例えば、次のようにプロパティごと返そうとしてもエラーになります。

$type: ocean;

p {
  if($type == ocean, color: blue, color: black);
}

複数の条件分岐があるケースはこのようになります。ただし、コードの可読性が落ちるので、素直に @else if を使ったほうがよいように思います。

$type: monster;

p {
  color: if($type == ocean, blue, if($type == matador, red, black));
}

このように、使い道は @if ディレクティブよりも限定されますが、うまく使うと、スマートにコードを書くことができます。例えば、以下は Compass の中で実際に使われている事例です。

@mixin transform-origin(
  $origin-x: $default-origin-x,
  $origin-y: $default-origin-y,
  $origin-z: false,
  $only3d:   if($origin-z, true, false)
) {
  $origin: unquote('');
  @if $origin-x or $origin-y or $origin-z {
    @if $origin-x {
      $origin: $origin-x;
    } @else {
      $origin: 50%;
    }
    @if $origin-y {
      $origin: $origin $origin-y;
    } @else {
      @if $origin-z {
        $origin: $origin 50%;
      }
    }
    @if $origin-z {
      $origin: $origin $origin-z;
    }
    @include apply-origin($origin, $only3d);
  }
}

第 4 引数 $only3d の初期値は、第 3 引数 $origin-z の値によって truefalse がセットされるようになっていますが、if 関数を使うことで非常にわかりやすいコードになっているのが見てわかるかと思います。

というわけで、if 関数の紹介でした。