Sassでlinear-gradient()のmixinをつくる その2

誰がうれしいのかわからない、CSS Preprocessor Advent Calendar 2012の記事の第2弾です。
今回は -webkit-gradient() への変換について書こうと思ったのですが、ひとつ忘れてたことがあったので、それについて書きます。

Part 4 ― type_of() で処理を振り分け

前回は「方向なし」「キーワード」「角度」別に3つのmixinを定義しました。分けるとそれぞれ何をやってるかがわかりやすいのですが、やはり使うことを考えると一つにまとめたいもの。そこで、ひとつのmixin内で処理を振り分けることにします。

やり方ですが、Sassの type_of() 関数を使います。mixinの引数を第一引数と可変長引数のふたつにわけ、第一引数の型を判定します。

@mixin lg-compound($first, $rest...) {
    $prefixes: '-webkit-';

    // 出力用の変数
    $direction: false;
    $legacy_direction: false;
    $colorstops: false;
    
    // $first が color を含む → 方向がない → パート1
    @if type_of(nth($first, 1)) == 'color' {
        // direction って名前よくないね
        $direction: $first;
        $legacy_direction: $first;
        
        $colorstops: $rest;
    }
    // $first がリスト → キーワードかも → パート2
    @else if type_of($first) == 'list' {

        // 標準のキーワード
        $standard_keywords:
            to bottom, to left, to top, to right,
            to top left, to top right,
            to bottom right, to bottom left,
            to left top, to right top,
            to right bottom, to left bottom;
            
        // 接頭辞版のキーワード
        $legacy_keywords:
            top, right, bottom, left,
            bottom right, bottom left, top left, top right,
            right bottom, left bottom, left top, right top;
        
        // キーワードのインデックスを取得
        $idx: index( $standard_keywords, $first );

        @if $idx {
            $direction: $first;
            $legacy_direction: nth($legacy_keywords, $idx);
            $colorstops: $rest;
        }
    }
    // $first が number → 角度かも
    @else if type_of($first) == 'number' {
        // unit() 関数で角度 (deg) かを確認
        // deg の場合 → パート3
        @if unit($first) == 'deg' {
            $direction: $first;
            $legacy_direction: (450 - $first) % 360;
            $colorstops: $rest;
        }
    }
    // それ以外はエラー
    @else { /* エラーですよん */ }
    
    // カラーストップが確認できたら出力
    @if ($colorstops) {
        @each $prefix in $prefixes {
            background-image: #{$prefix}linear-gradient(
                $legacy_direction, $colorstops);
        }
        background-image: linear-gradient($direction, $colorstops);
    }
}

前回はあまり引数のチェックをしてなかったのですが、ちょっと細かくしてみました。

まず color のチェックは、#fff 0% など、カラーストップに位置指定があることを考えて type_of(nth($first, 1)) と、「最初の最初」の型をチェックしています。

キーワードのチェックでは、list であるかをまず確認します。その上でリストの最初に 'to' があるかを確認しています。

角度の場合は、まず number かをチェックし、その上で unit() 関数を使い単位が 'deg' かを確認しています。これは、Sassにおいて数値と単位からなるものは number に属することを利用しています。

まとめ

type_of() を使って引数の型を調べることで、型にあわせて処理を振り分けられるようになりました。また、値のチェックを詳しくしてみました。

というわけで、つぎこそ -webkit-gradient() の出し方について書こうと思います。