こんにちは。
年末の予定はぶっ通しでスカイリムにつぎ込むことが決定したUIT富田です。
今回は、Less & Sass Advent calendar 2011の6日目として、
sassのfunctionについて解説します。
すっぽりハマった四則演算の落とし穴
sassは値の四則演算をサポートしており、10進数だけでなく、16進数の値であってもよしなに計算してくれます。
color: #a3a4a5 + #111111;
↓
color: #b4b5b6;
16進数と10進数でもエラーにならず計算してくれます。(普通あまりやらないとは思いますが)
color1: #000000 + 1;
color2: #000000 + 15;
↓
color1: #010101;
color2: #0f0f0f;
この16進数の計算は、結果が#fffffを上回った場合、上回った分は切り捨てて、すべて#ffffffとして計算します
color: #999 + #fff;
↓
color: #ffffff;
上記の例では、切り捨ててくれてありがとう、という感じですが、例えば任意の$color1と、$color2の中間色を設定したいケースではどうでしょうか。
$color1:#999999;
$color2:#cccccc;
color: ($color1 + $color2)/2;
999999と#ccccccの中間色である#b2b2b2を出力させたいのですが、この例で実際に出力してみると#7f7f7fとなってしまいます。
これは、#999999 + #ccccccの結果が#ffffffを上回ってしまったことで、#ffffff / 2として計算されてしまうためです。
正しく中間色をとるためには、一旦16進数を10進数に変換し、必要な計算をしたあと、10進数を16進数に戻すという処理が必要になりそうです。やってられっか
それfunctionでできるよ
実はそんなめんどくさいことをしなくても、もっと簡単な魔法が用意されていました。
color: mix($color1 , $color2 ,50%);
これだけです。
これで、$color1と、$color2の中間色をCSSに出力してくれます。
まさに魔法。functionとは、キーワードと対象を指定することで、キーワードに応じた処理を対象に施し、その結果を返してくれるものです。上記の例では、mixがキーワード、()の中身のコンマ区切りの値が対象になります。
どんな処理をするかはキーワードによって異なりますが、sassはデフォルトで用途に応じたディモールトベネなキーワードが用意されています。
今回用いたmixも、デフォルトで用意されたfunctionの1つです。
デフォルトの関数は以下にまとまっています。
http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html
これだけは知っておきたいfunction
今回はその中から特に、mixinを作る際などに重要になってくる抑えておきたい以下のfunctionを紹介します。
- Number Functions
- Introspection Functions
- String Functions
- List Functions
というか上記以外は色の操作がほとんどで、
関数名を見ればだいたいどんなものか分かるかと思うので、ここでの紹介は省きます。
Number Functions
数値 / 数値の式をパーセンテージに変換したい
percentage($value)
percentage(100px / 50px)
↓
200%
数値を小数点以下四捨五入したい
round($value)
round(10.4px)
↓
10px
数値を小数点以下切上げたい
ceil($value)
ciel(10.4px)
↓
11px
数値を小数点以下切捨てたい
floor($value)
floor(10.4px)
↓
10px
数値の絶対値を取得したい
abs($value)
abs(-10px)
↓
10px
Introspection Functions
値の型を取得したい
type-of($value)
type-of(#fff)
↓
color
値の単位を取得したい
unit($number)
unit(100px)
↓
"px"
値に単位がついていないかどうかを取得したい
unit($number)
unitless(100px)
↓
false
2つの値が、合計したり比較したりできるかどうかを取得したい
comparable($number-1, $number-2)
comparable(100px, 3em)
↓
false
String Functions
クォートしたい
quote($string)
$val : hogehoge
quote($val)
↓
"hogehoge"
アンクォートしたい
unquote($string)
$val : "hogehoge"
unquote($val)
↓
hogehoge
List Functions
sassでは、以下のようにカンマ区切りやスペース区切りで指定された値をもつ変数を、リストとして操作することができます。
$list : jojo dio polnareff abdul;
$list2 : star,world,knight,magicean;
リストの項目数を取得したい
length(list)
length($list)
↓
4
リストのn番目の項目を取得したい
nth(list,n)
length($list 3)
↓
polnareff
ある項目が、リストの中の何番目にあるか取得したい
index(list, value)
index($list, dio)
↓
2
リストの末尾に追加したい
append(list,val)
append($list,iggy)
↓
jojo dio polnareff abdul iggy;
リストを結合したい
append(list,list)
append($list, $list2)
↓
jojo dio polnareff abdul star world knight magicean;
リストを順番に組み合わせたい
zip(*list)
zip($list, $list2)
↓
jojo star,dio world,polnareff knight,abdul magicean;
※リファレンスでは出力は上記となっていますが、
実際は以下のように出力されたため、こちらは正しい実装で動作していないようです。
jojo dio polnareff abdul, star world knight magicean
特にList Functionsは、制御構文(if,for,each,while)を組み合わせることで、
例えば、”クラス名と同名の背景画像をもつ要素を、クラス名の数で均等に割ったwidthで並べたい”というような複雑なケースでも、簡単に書くことが可能になります。
$classList : jojo dio speedwagon danni;
@each $list in $classList{
.#{$list} {
width:100% / length($classList);
background-image: url('/images/#{$list}.png');
float:left;
}
}
↓
.jojo{
width:25%
background-image: url('/images/jojo.png');
float:left;
}
.dio{
width:25%
background-image: url('/images/dio.png');
float:left;
}
.speedwagon{
width:25%
background-image: url('/images/speedwagon.png');
float:left;
}
.danni{
width:25%
background-image: url('/images/danni.png');
float:left;
}
〇〇の機能はないの?
なければ自分で作りましょう。@functionを使って、自分でfunctionを定義することができます。
@function ファンクション名($引数) {
@return 処理;
}
以上が、sassのfunctionの簡単な紹介です。
functionはめんどうな作業を代わりにやってくれる便利な魔法です。
上手に活用して定時に帰りましょう。