ぽんぽこ開発日記

主にHTML, CSS, JavaScriptなどフロントエンドの話を。目指せ脱初心者。

Sassにおける@extendと@mixinの違いとその使い分け

Sassは非常に便利なのは重々承知です。その恩恵はありがたくいただいております。ただ個人的にはSassが優秀すぎてどこまで効率的にできるのかいまいちわかっていない部分があります。そんなわけで今回は@extendと@mixinの違いについて整理をば。

@extendの特徴

@extendが行なってくれることを一言で表すと「継承」です。つまり受け継ぐわけなんです。なにを言っているのかわからない!って僕も最初思ったので実際にコードにしてみました。
f:id:noriven:20140817002855p:plain
[HTML]

<div class="box1">コメント表示エリア(高さ250px)</div>
<div class="box2">コメント表示エリア(高さ300px)</div>
 

[Sass]

.box-base{
     float: left;
     width: 200px;
     height: 200px;
     border:1px solid #aaa;
     background: #ddd;
     margin:10px;
}

.box1{
     @extend .box-base;
     height: 250px;
}

.box2{
     @extend .box-base;
     height: 300px;
     background: #9E566C;
}
 


[CSS]

.box-base, .box1, .box2 {
  float: left;
  width: 200px;
  height: 200px;
  border: 1px solid #aaa;
  background: #ddd;
  margin: 10px; }

.box1 {
  height: 250px; }

.box2 {
  height: 300px;
  background: #9E566C; }
 

Sassを変換して出力されたCSSを見比べてみましょう。
@extendを使うと、 .box-base, .box1, .box2{…} といったようにグルーピングが行われ、その後.box1や.box2といった個別のクラスが定義されるようになっています。この@extendの特徴をまとめると

  • 何重にも同時にいくつも@extend(継承)できるためカスタマイズはどこまでもできる
  • コード量が少なくなる
  • 一つのクラスをわざわざ分別して設定するためメンテナンスしにくい

といったところになります。


@mixinの特徴

f:id:noriven:20140817002910p:plain
[HTML]

<p class="alert-error">入力された情報が正しくないため送信がキャンセルされました。</p>
<p class="alert-warning">本当にこの情報で登録してよろしいですか?</p>
 

[Sass]

@mixin alert($color: #ddd){
     width: 50%;
     border-radius: 5px;
     border:1px solid $color;
     font:bold 14px san-self;
     color: $color;
     padding:10px;
     background: lighten($color, 40%);
}

.alert-error{
     @include alert(#C6331F);
}

.alert-warning{
     @include alert(#A09A2C);
}
 

[CSS]

.alert-error {
  width: 50%;
  border-radius: 5px;
  border: 1px solid #c6331f;
  font: bold 14px san-self;
  color: #c6331f;
  padding: 10px;
  background: #f5c3bc; }

.alert-warning {
  width: 50%;
  border-radius: 5px;
  border: 1px solid #a09a2c;
  font: bold 14px san-self;
  color: #a09a2c;
  padding: 10px;
  background: #e9e6af; }
 

いきなりのコードで失礼しました。ただ@mixinの場合、コードを読めば直感的に特徴が読み取れるのではないでしょうか。まとめますと

  • @mixin name{…}の部分はCSSファイルには出力されない
  • まずグルーピングされる@extendとは反対に一つのクラスを複数に分別して出力されないためメンテナンスしやすい
  • OOCSSの「構造と見た目の分離」がしやすい(上記例だと「alert」という構造と「error」「warning」という見た目を分離して書ける)
  • 引数を持たせることができるため、カスタマイズしやすい。



結論として…

上記で@extendと@mixinの特徴を整理してみました。パッとみると、メンテナンス性・カスタマイズ性の面から@mixinがいいじゃん!って思うかもしれません。しかし、どっちも使い方を間違えればメンテナンス性・カスタマイズ性が大幅に損なわれます。
プロジェクトやサイト規模によって往々にして変化するかもしれませんが、僕個人としては以下の使い分けを心がけています。

(特に静的サイトやワードプレス

・制作側と編集側が異なり、編集側がCSSしか使えない場合は@extendを使う。

例えばワードプレスなどがそうですね。制作側はSassで作ったほうが早いのでSassを利用し、納品後のCSSメンテナンスはそのワードプレスを使ったウェブサイトを運営する編集側に任せる。

(特にウェブサービスなど)

・@extendはclearfixやdisplay:noneを使う場合に利用する

いろんなところでclearfixをつけたりdisplay:noneにするシーンがあるかと思います。そういうチップスみたいなものを追加したいときは継承で済ませたほうが良いだろうってことで@extendを使うようにしています。

・OOCSSに準ずる場合は基本的に@mixinを出来る限り利用する

さきほどの例にも出ているように@mixinを使うとOOCSSの「構造と見た目の分離」が直感的にでき、かつメンテナンス性・カスタマイズ性を向上させることができます。なので出来る限り@mixinで、どうしても@extendでやらないといけない場合のみ@extendを使う、というスタイルで使い分けます。(まだそのような状況に遭遇したことはありません)


日ごろ、Sassを使ってコーディングをしているのですが、いまいち@extendと@mixinの使い分けができておらず、他の人が作ってくれた@extendやら@mixinやらを使い回すのみ、という状況にあったため、「これはヤバい。さっさと習得せねば」という思いが胸でいっぱいになったため頑張って整理してみました。