LINE株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。 LINEヤフー Tech Blog

Blog


sassの抑えておきたいfunctionの使い方

こんにちは。
年末の予定はぶっ通しでスカイリムにつぎ込むことが決定した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はめんどうな作業を代わりにやってくれる便利な魔法です。
上手に活用して定時に帰りましょう。