Categories
CSS Sass

Sassの可変長引数で出来ること出来ないことまとめ

Sassでの可変長引数の機能は、ver.3.2.0から追加された機能です。まだ何ができて何ができないのかがよく分かりません。実験して気づいたテクニックなどを記載していますので、是非参考にしてください。サンプルとして以下の記事でも記述していますので、見て頂けたらと思います。

「Sassでbox-shadowを@mixin化する – 可変長引数を使おう」

可変長引数に空の内容を渡せない

今まで使用してきた@mixinの使用方法の一つで、デフォルト引数というものがありました。デフォルト引数を指定しておくことで、呼び出し時に指定しなくてもデフォルト値が利用されます。以下のような使い方です。

@mixin mixinTest($value: 0) {
    @debug $value;
}

こうすることで、以下のような呼び出しが可能です。

@include mixinTest();
@include mixinTest;

実際に使用している記事は以下となります。サンプルも載せていますので参考にしてみてください。

「Sassで角丸の矩形を超簡単に記述する方法」
「Sassを使って面倒なCSS3を簡単に書いてしまう – プロパティ名にも変数を使おう」
「Sassを使って矢印を描こう – CSSテクニック」

汎用性があり使いやすいですね。では可変長引数も汎用性を高めるために同様のことをしたいと考えたとします。しかし、以下のソースはコンパイルエラーとなってしまいます。

@mixin mixinTestValiable($value... : 0) {
    // コンパイルエラー
}

また、以下のような方法で、$valueにデフォルトの値をもたせようとしても、もちろんコンパイルエラーとなります。

@mixin mixinTestValiable($value...) {
    $value: 0 !default;

    // ここでコンパイルエラー
    @debug $value;
}

これは空の$valueが生成されていることにより、!defaultが無視されているためです。しかし、ここで注目して頂きたいのは「空の変数を使用するまでコンパイルエラーではない」ことです。

可変長引数に空の内容を渡す

空の内容かどうかを判別できれば、デフォルトの変数を指定することができます。そのテクニックが以下となります。

@mixin mixinTestValiable($value...) {
    @if(length($value) == 0) {
        // 可変長引数が空であった場合の処理
    }
    @else {
        // 可変長引数が空でない場合の処理
    }
}

これは、Sassの仕様上、長さ0のリストを作ることができないのでこのテクニックが使えます。空のデータを入れたリストであっても、空のデータが入ったリストとして長さが1となってしまうためです。こういった処理の構造は@function化してしまいましょう。

@function existed($value...) {
    @if(length($value) == 0) {
        @return false;
    }
    @else {
        @return true;
    }
}

このexisted()関数は以下のように使用します。処理に名前が付くことで可読性が向上します。

@mixin mixinTestValiable($value...) {
    @if(not existed($value...)) {
        // 可変長引数が空だった場合の処理
    }
}

では本題の、空の可変長引数でも動作するように作成した@mixinは以下になります。

$DEFAULT_mixinTestValiable: 0 !default;
@mixin mixinTestValiable($value...) {
    @if(not existed($value...)) {
        $value: $DEFAULT_mixinTestValiable;
    }
    // 以下処理に続く
}

グローバル変数であるデフォルト変数を利用することで、引数を指定しない呼び出しでも正常に動作するようになりました。

可変長引数とリスト変数との違いは?

Sassのバージョンが3.2.0以前では、可変する内容を@mixinや@functionに渡すためにリストが用いられてきました。リストは以下のように作ることができます。

$value: 0, 1, 2, 3;

カンマで区切られているのがリストとして認識されます。実際に確かめてみましょう。可変長引数との型の違いを見るためにtype-of()関数を利用します。

@mixin mixinTestValiable($value...) {
    @debug type-of($value);
    
    $list: 0, 1, 2, 3;
    @debug type-of($list);
}

コンパイルの結果は以下のようになります。

Line 76 DEBUG: arglist
Line 80 DEBUG: list

可変長引数の型はarglist、リストの型はlistと表示されています。この違いを見るために、リストを操作する関数を利用してみます。length()関数はリストを引数に取り、リスト内の要素数を返します。

@mixin mixinTestValiable($value...) {
    @debug length($value);
    
    $list: 0, 1, 2, 3;
    @debug length($list);
}

こうやって確認すると、どちらもリストの数、つまり「,(カンマ)」で区切られた要素の数を返します。実質、どちらもリストとして使用できることが分かりました。そのため、リスト変数を以下のように可変長引数に渡しても正常に動作します。

$list: 0, 1, 2, 3;
@include mixinTestValiable($list);

可変長引数以外に引数を指定する

可変長引数の前に、通常の引数を使用することができます。

@mixin mixinTestValiable($value1, $value2...) {
    // value1は通常の引数
    // value2は可変長引数
}

しかし、可変長引数の後に通常の引数を使用することはできません。これは、可変長引数に渡す引数と、$value1に渡す引数が区別できないためでしょう。

@mixin mixinTestValiable($value2..., $value1) {
    // コンパイルエラー
}

また、通常の引数であってもデフォルト引数を指定することはできません。

@mixin mixinTestValiable($value1: 0px, $value2...) {
    // コンパイルエラー
}

mixinTestValiable()を使用する際は、以下の書き方ができます。

@include mixinTestValiable("value1", "value2", "value2", "value2");

1つ目の”value1″は、$value1として使用することができます。2つ目の引数以降は$value2のリストとして使用することができます。では引数を指定する書き方はどうでしょうか。

@include mixinTestValiable($value1: "value1", $value2:"value2", "value2", "value2");

引数の指定もコンパイルエラーです。可変長引数を利用する際は、その他の引数を利用すると制限が多いため、可変長引数だけを利用した方がよさそうです。

 
以上が可変長引数の動作まとめになります。動作がまだまだ一貫していないため、使いにくいかもしれません。しかし、受け取る引数がリストであることを明示できた上でリストとしてふさわしくない使用を行うとコンパイルエラーとなるため、個人的におすすめしたいと思います。

1 reply on “Sassの可変長引数で出来ること出来ないことまとめ”

[…] TEST CORDING » Sassの可変長引数で出来ること出来ないことまとめ Posted 2012年8月31日 Check TEST CORDING » Sassの可変長引数で出来ること出来ないことまとめSassでの可変長引数の機能は、ver.3.2.0から追加された機能です。まだ何ができて何ができないのかがよく分かりません。実験して気づいたテクニックなどを記載していますので、是非参考にしてください。サンプルとして以下の記事でも記述していますので、見て頂けたらと思います。 「Sassでbox-shadowを@mixin化する – 可変長引数を使おう」 可変長引数に空の内容を渡せない 今まで使用して… >>TEST CORDING » Sassの可変長引数で出来ること出来ないことまとめ Author: […]

Leave a Reply

Your email address will not be published. Required fields are marked *