Sassの勉強 #07 柔軟なスタイル定義が出来る「@mixin」
@mixin 基本
「@mixin」はスタイルを定義しておき、それを好きなところで呼び出せるという機能。それだけだと「@extend」と変わらないって感じなのですが、「@mixin」では引数が使えちゃう(*´∀`)!
…と興奮気味ですが、さっそく基本の使い方をみていきます。
ミックスインの使い方
まず「@mixin 任意の名前{・・・}」という形でミックスインを定義します。
// ミックスインを定義 @mixin mixinTest{ width:100%; color:#000; padding:10px; margin:0 auto; }
定義しただけではCSS側には何も出力されませんので、その定義したミックスインを「@include 任意の名前;」で呼び出します。
// インクルードで呼び出す #sample{ @include mixinTest; }
そうすると、CSS側への出力はこうなります。
#sample { width: 100%; color: #000; padding: 10px; margin: 0 auto; }
定義した「mixinTest」の内容が、「#sample」の中に展開されているのが確認できます。
ミックスインは「@mixin」と「@include」をセットで使う ←覚える。
ここまでは「@extend」でも可能なのですが、ミックスインを使った場合、使用するルールセットが増えた場合でもセレクタのグループ化はされません。
先ほどとまったく同じ例ですが、今度は定義したミックスインを別のセレクタのルールセットにも呼び出してみます。
// ミックスインを定義 @mixin mixinTest{ width:100%; color:#000; padding:10px; margin:0 auto; } #sample01{ @include mixinTest; } #sample02{ @include mixinTest; }
「@extend」の場合なら「#sample01」「#sample02」のセレクタはグループ化されますが、ミックスインの場合はグループ化されずに出力されます。
/* コンパイル後 */ #sample01 { width: 100%; color: #000; padding: 10px; margin: 0 auto; } #sample02 { width: 100%; color: #000; padding: 10px; margin: 0 auto; }
そのほかにも「@extend」との違いがあります。ミックスインのすごいとこは下記のような機能が使える事です。
引数を使う
引数って何よという説明は省きますが、さっそく簡単な例を。
引数を使用する場合はミックスイン名の後に「()丸括弧」をつけて、その中に引数を書きます。引数を複数指定する場合は「,(カンマ)」区切りで指定します。
@mixin ミックスイン名(引数){・・・} 引数の数は必要なだけ,区切りで指定。
// ミックスインを定義 @mixin test-border($color, $width) { border: { color: $color; width: $width; style: dashed; } } // ミックスインを呼び出し #test{ @include test-border(blue, 1px); }
「test-border」というミックスインにスタイル定義しました。それを#testで呼び出しています。@mixin test-border($color, $width) の部分、引数に「$color」「$width」をセットしています。この引数(変数)の値を@include時に指定してやると(上の例では「(blue, 1px)」)コンパイル後のCSSは下記のようになります。
#test { border-color: blue; border-width: 1px; border-style: dashed; }
違うセレクタで呼び出す際、引数の値を変えればその部分だけ指定した値が反映されて出力されます。
// ミックスインを定義 @mixin test-border($color, $width) { border: { color: $color; width: $width; style: dashed; } } // ミックスインを呼び出し #test{ @include test-border(blue, 1px); // blue, 1px } #test2{ @include test-border(blue, 3px); // blue, 3px } /* コンパイル後 */ #test { border-color: blue; border-width: 1px; border-style: dashed; } #test2 { border-color: blue; border-width: 3px; border-style: dashed; }
引数のデフォルト値を定義する
この引数に予めデフォルト値を定義しておくことも可能です。書き方は引数の後に「:」と値を書きます。
@mixin ミックスイン名(引数: デフォルト値){・・・}
// ミックスインを定義 @mixin test-border($color, $width: 1px) { border: { color: $color; width: $width; style: dashed; } } // ミックスインを呼び出し #test{ @include test-border(blue); // $widthの値を省略 } #test2{ @include test-border(blue, 3px); } /* コンパイル後 */ #test { border-color: blue; border-width: 1px; border-style: dashed; } #test2 { border-color: blue; border-width: 3px; border-style: dashed; }
「#test」の方では「@include test-border(blue); 」と$widthの値を省略して記述しましたが、$widthにはデフォルト値が予め指定してあるので、コンパイル後のCSSにはデフォルトの1pxが出力されているのが分かります。
また、下記のように引数と値を明示的に表して記述することも可能です。わかりやすくする用。この場合もまたミックスインの定義で引数にデフォルト値を指定している場合は省略可能。
#test03{@include test-border($color: red);} #test04{@include test-border($color: red, $width: 2px);} /* コンパイル後 */ #test03 { border-color: red; border-width: 1px; border-style: dashed; } #test04 { border-color: red; border-width: 2px; border-style: dashed; }
また同じミックスインの例ですが、下記のように全ての引数にデフォルト値を指定している場合は、@include時に()自体を省略できますし、()のみを記述することもできます。どちらもコンパイル後のCSSソースは同じになります。
// ミックスインを定義 @mixin test-border($color:blue, $width: 1px) { border: { color: $color; width: $width; style: dashed; } } #test05{@include test-border;} // ()を省略 #test06{@include test-border();} // ()だけを記述 /* コンパイル後 */ #test05 { border-color: blue; border-width: 1px; border-style: dashed; } #test06 { border-color: blue; border-width: 1px; border-style: dashed; }
「,(カンマ)」が必要なプロパティには可変長引数「…」を利用
「,(カンマ)」が必要なプロパティ、text-shadowやbox-shadowについてですが、これらの値を引数として使いたい場合は注意が必要。そのまま「,(カンマ)」区切りで値として使用するとエラーになります。
ミックスインでは、引数1つにつき、1つの値しか渡せないというルールがあるそうです。故に「,(カンマ)」区切りで分数の値を渡そうとするとエラーになる、と。
そこで「… (ドット3つ)」という特別な引数を使います。
リファレンス見ながら「Variable Arguments」って何て訳すんやと思ったらしっかり教科書に書いてあったでござる。「…」←可変長引数といいます。
@mixin box-shadow($shadows...) { -moz-box-shadow: $shadows; -webkit-box-shadow: $shadows; box-shadow: $shadows; } .shadows { @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999); } /* コンパイル後 */ .shadows { -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; box-shadow: 0px 4px 5px #666, 2px 6px 10px #999; }
このように「… (ドット3つ)」の可変長引数を利用することでエラーを回避して意図したとおりにコンパイルできます。
文字列やリストとして値を渡したりすればエラーを出さずに出力できるらしいのですが、やっぱり面倒だし可読性が落ちたりするので、可変長引数「…」を使うのが一番良いっぽいです。
複数の引数を持つミックスインで可変長引数「…」を利用
複数の引数を持つミックスインを@includeする際にも可変長引数「…」を利用することができます。引数の値を一旦任意の変数に「,(カンマ)」区切りで代入しておいて、@include時に引数の()の中に「$変数名…」という形で指定します。
@mixin colors($text, $background, $border) { color: $text; background-color: $background; border-color: $border; } $values: #000, #fff, #f00; // 引数の値を$valuesへ代入 #test{ @include colors($values...); //$valuesと可変長引数「...」を()へ } /* コンパイル後 */ #test { color: #000; background-color: #fff; border-color: #f00; }
使い回しするミックスインの引数の値をファイルのどこか1か所で管理して任意の場所で呼び出したい時とか、引数の値以外は触られたくない時とかに便利なのかなぁ。
ミックスインのスコープ
ミックスインもスコープを持ちます。
セレクタのルールセット内で定義したミックスインはそのセレクタの中でしか使えません。
#test{ @mixin testMargin{ margin:50px; } .testContents{ @include testMargin; } @include testMargin; } /* コンパイル後 */ #test { margin: 50px; } #test .testContents { margin: 50px; }
上の例で「#test」内に書いた@mixin testMarginは「#test」内でしか使えません。外から呼び出そうとするとエラーになります。
@content
「@content」はミックスインにコンテンツブロックを渡すための機能です。渡されたコンテンツブロックは「@content」の位置で展開される。今までの@includeでミックスインを呼び出していたのとはちょっと違う。
リファレンスの例。
@mixin apply-to-ie6-only { * html { @content; } } @include apply-to-ie6-only { #logo { background-image: url(/logo.gif); } } /* コンパイル後 */ * html #logo { background-image: url(/logo.gif); }
最初なんか意味がわからなかったのですが、「それ」に対してコンテンツブロック(ルールセットやスタイル)をつっこめるという事だと思います。(なんか文章で説明すんのこれも難しいのですが)
目的は記述量を減らす事と可読性を上げる事なので、無理に使う必要はなさそうだけれども、使いこなせたら便利そう。特にハックやメディアクエリの絡むソースとかので威力を発揮できそうです。
Sassの教科書の「レスポンシブWebデザイン対応で楽をするため、@content を活用する」というサンプルがすごくわかりやすかったです。何度も教科書のサンプルソースを引用してくるのも気が引けるのでリンクだけおいておきます。←興味のある方は教科書を買って一緒に勉強しましょうぜというお誘い。
ミックスインのスニペットとか色々気になったサイト まとめ
眺めただけでワクワクしてしまう素敵ミックスインのライブラリとかスニペット集とか。気になったページでブクマしていたもののリストですので、全部試したわけではありませんが、発想のヒントがいっぱい!(compassなど総合的なでっかいフレームワークはとりあえず省いてます)
- Bourbon – A Sass Mixin Library
- Animate Mixin for Compass/SASS
- 15 essential Sass mixins | Developer Drive
- 【Sass】新規でサイトを作るのに使えそうなの一式。Ver 1 – CSS HappyLife
- Sassを使ったコーディングの強い味方に!便利なextend&mixin集を作ってみた | 株式会社LIG
- Sassで作ったオレオレグリッドシステムが便利過ぎる。 | 90zbear.com
- Sache: Find Sass and Compass Extensions for your next project
- This gist demonstrates some uses of the new sass feature: Passing content blocks to mixins.
- nonakaryuichi/scss_media_queries · GitHub
- CSS3 buttons by Chad Mazzola
- Z63 | 8 Sass mixins you must have in your toolbox
- matthieua/sass-css3-mixins · GitHub
内容が重複しているようなものもまとめてリストにつっこみましたが、どれも楽しそうでいい感じです。
Sassの勉強 関連記事
- Sassの勉強 #00 もっかい最初からやり直そうSassの巻
- Sassの勉強 #01 Sassとは何か?~環境構築
- Sassの勉強 #02 Sassの基本的な機能「ネスト」
- Sassの勉強 #03 Sassの基本的な機能「変数」
- Sassの勉強 #04 Sassの基本的な機能「演算」
- Sassの勉強 #05 Sassの基本的な機能「@import」
- Sassの勉強 #06 スタイルの継承ができる「@extend」
- Sassの勉強 #07 柔軟なスタイル定義が出来る「@mixin」
- Sassの勉強 #08 制御構文(条件分岐・繰り返し)
- Sassの勉強 #09 @at-root
- Sassの勉強 #10 Sassの勉強 #10 関数一覧(Ver.3.4) と自作関数