気付けば、Vol.10!
ずいぶん長編になってまいりました。

何気に、既に去年1年分のエントリー数を超えてるだなんて!
今年が頑張ってるのか去年がひどすぎたのかは、ボクには分かりません。

・・・はい、後者です。

さてさて、Vol.4のSassの基本的な記述方法で書いた「ミックスイン」に関して、もうちょい書いてみたいと思いますが、ミックスインは奥が深くてこれから触れる内容も、触り程度って感じだと思いますが、それでも、タイトルに有るように、スマホ案件なんかではかなり活躍しちゃいます!

ミックスインついでに、@if 、@each 辺りもカンタンにですが触れていきます。
ここまで来ればだいぶSassを使いこなしてる様な気がしますよ!たぶん。

や、日本初の Sass エヴァンジェリストである @kotarok さんみたいな超上級者な方々からしたら、鼻をほじほじしながら ( ´_ゝ`)フーン 程度なんでしょうけど!


ミックスインのおさらい

まずは、カンタンにおさらいです。

Sass

// ミックスインを定義
@mixin inline_block {
	display: inline-block;
	*display: inline;
	*zoom: 1;
}
 
// 定義したミックスインを読み込む
.sampleBox {
	@include inline_block;
	background: #eee;
}

@mixin の後に半角スペースで、任意の名前を定義し、@include で定義したミックスインを読み込む事が出来ます。
これをCSSに変換すると次のようになります。

CSS

.sampleBox {
	display: inline-block;
	*display: inline;
	*zoom: 1;
	background: #eee;
}

これだけだと、@extend と大差がないので、ミックスインじゃないと出来ない事をご紹介していくです。

変数と合わせて利用する

ミックスインは次のように変数と合わせて使うことが出来ます。

Sass

@mixin min_height($value) {
	min-height: $value;
	_height: $value;
}
 
.sampleBox {
	@include min_height(500px);
}

こんな風に、定義した名前の後に()でその中に変数名をセットし、インクルードする際に、変数の値を()内に入れます。
これで、CSSに変換すれば次のようになります。

CSS

.sampleBox {
  min-height: 500px;
  _height: 500px;
}

更に、変数名だけじゃなく値ももちろん定義出来ます。その際は「:」を使ってその後に値を入れます。
これで、初期値をセットしておけます。

Sass

@mixin min_height($value: 200px) {
	min-height: $value;
	_height: $value;
}
 
// 初期値が上書きされる
.sampleBox1 {
	@include min_height(500px);
}
// 初期値が適用される
.sampleBox2 {
	@include min_height();
}

初期値を適用する場合は() が無くても大丈夫です。
これを、CSSに変換すれば次のようになります。

CSS

.sampleBox1 {
  min-height: 500px;
  _height: 500px;
}
.sampleBox2 {
  min-height: 200px;
  _height: 200px;
}

基本的な値は共通だけど、部分的に値を変更したい場合なんかに活用できる感じです。
ちなみに、値が同じ場合は次のようにしても問題無いです。

Sass

@mixin min_height {
	$value: 200px;
	min-height: $value;
	_height: $value;
}

値が固定なら、 @extend のが良いんですけど。
こんな感じで、変数と組み合わせることで、同じような記述を何度もしなくて済むので、ベンダープレフィックスを使うことが多いスマホ案件等で力を発揮出来ます。
border-radius 辺りがよく例に出てますが、その辺りは後述します。

@if を使ってみる

ちょっと方向がずれますが、ここで @if に関して軽く扱っておきます。

if とかマジでプログラマーな領域な感じがしますが、ボクは複雑なことは分からないのであくまでもカンタンな使い方です。アレルギーな方でも大丈夫!

if は、プログラムでは「もし~だったら」という条件を示すヤツですね。
例えば、次のように使うことで、リセットCSS的なのを1ファイルで済ませることが出来ます。

Sass

// HTML5の場合は値を「false」から「true」にする
$use_html5: false;
 
@if $use_html5 {
	// ここに HTML5のリセットスタイルを記述する
} @else {
	// ここに XHTMLのリセットスタイルを記述する
}

ファイルを分割することがメリットになる場合もあれば、こういう感じで同じリセットCSSでもDOCTYPEに寄って使い分けたい場合なんかには良いですね。

この辺りは、以下の記事などが参考になると思います。

ベンダープレフィクスを自動でやる

さて、ココがきっと主題になる感じです。
スマホ案件と言うかCSS3をそれなりに活用する案件の場合は、ベンダープレフィックスを都度付けるのが非常に面倒な作業ですよね。
そこで、Sassなら面倒なベンダープレフィックスを@each を使うことで自動で付けることが出来ます。
(先に@if をクッションにして@each に入ったつもりですがあんま意味が無かったかも!)

後述すると言った、border-radiusの例はここで登場です。

Sass

// 付与するベンダープレフィックス
$set_prefix: -webkit-, -moz-, -ms-, -o-, '';
 
// border-radius
@mixin border_radius($br_value: 3px) {
	@each $prefix in $set_prefix {
		#{$prefix}border-radius: $br_value;
	}
}
 
.sampleA {
	@include border_radius;
}
.sampleB {
	@include border_radius(50%);
}

これは、パッと見よく分かんない感じがしますが、最初に付与したいベンダープレフィックスを変数を利用して定義しておきます。
その後に、指定したリストを順番に処理してくれる @each を利用して、$set_prefix で定義したベンダープレフィックスを順番に処理しています。

これを、CSSに変換すると次のようになります。

CSS

.sampleA {
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  -ms-border-radius: 3px;
  -o-border-radius: 3px;
  border-radius: 3px;
}
 
.sampleB {
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  -ms-border-radius: 50%;
  -o-border-radius: 50%;
  border-radius: 50%;
}

こんな感じで、面倒な処理を自動で行なってくれます。
最初に付与したいベンダープレフィックスを変数で定義しているので、次のように色んな所で使いまわせます。

Sass

// 付与するベンダープレフィックス
$set_prefix: -webkit-, -moz-, '';
 
// border-radius
@mixin border_radius($br_value: 3px) {
	@each $prefix in $set_prefix {
		#{$prefix}border-radius: $br_value;
	}
}
@mixin border_radiusSH($br_tl_value, $br_tr_value, $br_bl_value, $br_br_value) {
	@each $prefix in $set_prefix {
		#{$prefix}border-radius: $br_tl_value $br_tr_value $br_bl_value $br_br_value;
	}
}
// box-size
.box_size {
	@each $prefix in $set_prefix {
		#{$prefix}box-sizing: border-box;
	}
}
 
.sampleA {
	@include border_radius(8px);
}
.sampleB {
	@include border_radiusSH(5px, 2px, 10px, 8px);
	@extend .box_size;
}

border-radiusプロパティは、値を個別で指定したい場合も有るので、それ用のミックスインを定義しています。
また、他のプロパティでも同じようにベンダープレフィックスを付与出来るので、box-sizingプロパティは @extend で使ったりもできます。

これをCSSに変換すると次のようになります。

CSS

.box_size, .sampleB {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
 
.sampleA {
  -webkit-border-radius: 8px;
  -moz-border-radius: 8px;
  border-radius: 8px;
}
 
.sampleB {
  -webkit-border-radius: 5px 2px 10px 8px;
  -moz-border-radius: 5px 2px 10px 8px;
  border-radius: 5px 2px 10px 8px;
}

この例ではしれっと、$set_prefix の値から -ms-, -o-,を消していたので、上記の様に変換されます。
こんな風に、CSS3をガンガン使う場合にかなり効率が上がると思います!

この辺りの繰り返し処理は、えどさんのエントリーが非常に参考になると思います。

Retina Display 対応もカンタンに

Sassを使えば、Retina Display の対応にも力を発揮します。

Sass

// 付与するベンダープレフィックス
$set_prefix: -webkit-, -moz-, -ms-, '';
 
// 画像のパス
$img_path: "../img/";
 
// background-size
@mixin bg_size($bgs_w, $bgs_h: auto) {
	@each $prefix in $set_prefix {
		#{$prefix}background-size: $bgs_w $bgs_h;
	}
}
 
ul {
	li {
		padding-left: 15px;
		background: url(#{$img_path}icon.png) no-repeat left center;
		@include bg_size(142px / 2);
	}
}

今までの機能を使ってるだけなので目新しいことはしてませんが、Retinaに対応する場合は、倍のサイズで作った画像の半分の値を指定する必要があったりするので、そんな場合も楽ちんになります。
これをCSSに変換すると次のようになります。

CSS

ul li {
  padding-left: 15px;
  background: url(../img/icon.png) no-repeat left center;
  -webkit-background-size: 71px auto;
  -moz-background-size: 71px auto;
  -ms-background-size: 71px auto;
  background-size: 71px auto;
}

と言う感じで

今回は、だいぶプログラムちっくな部分が出てきましたが、あんまりその辺り理解して無くてもミックスインなら何処かの誰かが頑張って書いてくれたのをコピペして使ったりすることが出来るので大丈夫かなーと。

もちろん、もっともっと勉強したい方は、色々ググッて使いこなしてもらって、覚えたことはアウトプットしてくれるとSassの情報が増えて皆がHappyになれるかなって思います!

これでSassを覚えよう!シリーズは、ほぼお終いです。
この次は、Sass用の新規でサイトを作るのに使えそうな一式を公開して、ボクがSassを覚えたのに参考にさせて頂いたサイトを出来るだけ上げたいと思います。