コーディングは知見を共有!デザインは勉強中のブログです!

Sass(scss)のextendとincludeの違いどういう時にどっち使えばいい?

コーダー、フロントエンドエンジニア、WebデザイナーでSassを使用されている方は多いと思います。

でもSassって色々便利に使える反面、最初はよくわからないものも多いですよね。
特に最初はネスト(入れ子)で記述するためだけに使ったり…といったつまみ食い使用も多いと思います。

特に変数やmixinでの指定をひとまとめにしたり、共通項をまとめて変更に強くしたりといった対応はよくされる方も多いんじゃないかなと。でも便利なのはわかるけど結構ぱっと見での理解が難しいものもありますよね。

その中でもひときわ紛らわしいのがextendとincludeかと思います。

extendやincludeはどちらもSassで使える機能の一つです。
共通な設定等をあらかじめ設定しておき、ほしいときに引っ張ってくることができます。
どちらも共通の設定を引っ張ってこれるものとしては同じですが

正直どっちつかえばいいの?

って思いません?
正直僕も全然わかりませんでした。
その辺を少し話せていけたらなと思います。

結局extendとincludeはどっち使えばいいの?

あざみ

どういう時に使い分けたらいいん?

いきなりですが、どっちかだけ使うならincludeを使用するのが良いかと思います。

終わり。

…というのもいささか味気ないですね。もう少しお話していきます。
共通化させたい用途によって最適解はことなります。
抽象的な表現をしてしまうなら「意味が同じのまとまり」をくくって共通化させたい場合はextend。
「共通化させたいものがたまたま同じ」ならincludeを使えばいいと思います。

といっても抽象度高いのでわかりづらいですよね。もう少し解説していきます。

そもそも共通化したい場合ってどういう時?

そもそもどういうときに共通化させたほうが便利なんだろ?って悩んでるあなた!
僕なりの考え方ですが一例としてまとめてみましたので参考にしてみてください。

まずいちばん単純なHTMLとCSSです。

例HTML

<p class="text-blue">
<p class="text-red">
<p class="text-green">

このようなhtmlがあるとします。

例CSS

.text-red {
	font-size: 14px;
	font-weight: 400;
	color: red;
}
.text-blue {
	font-size: 14px;
	font-weight: 400;
	color: blue;
}
.text-green {
	font-size: 14px;
	font-weight: 400;
	color: green;
}

そしてcssはこのような形。

これをある程度まとめさせ、メンテナンス性をあげたい場合にはいくつかの方法があります。

複数クラスで対応

複数クラスで対応

<p class="text text-blue">
<p class="text text-red">
<p class="text text-green">

.text {
//共通部分
	font-size: 14px;
	font-weight: 400;
}
.text-red {
	color: red;
}
.text-blue {
	color: blue;
}
.text-green {
	color: green;
}

これだけでもだいぶスッキリできますね。もちろんこのやり方もかなり応用が効くためgoodです。

複数クラスSass


.text{
//共通部分
	font-size: 14px;
	font-weight: 400;
    &-red{
        color: red;
    }
    &-blue{
        color: blue;
    }
    &-green{
        color: green;
    }
}

上記をSassで書くとこうなりますね。

extendとinclude

まずどういうときにどちらが良いか、何故迷うならincludeがいいのかという前に違いを理解しておきましょう。

ただこれはあくまで僕なりの見解になりますので正確にいえば多少違う可能性はありますし、別にextendを使用しても崩れたりするわけではないので慣れの問題もあるのかなぁと思う部分もあります。

extend

まずextendは継承といわれるもので、あらかじめ記述されている指定を引き継ぐ事ができます。
これによって共通項をもってこれるというわけですね。
具体例としては以下のような感じです。

extend

.text {
 font-size: 14px;
 font-weight: 400;
}

.text-red {
 @extend .text;
 color: red;
}

.text-blue {
 @extend .text;
 color: blue;
}

.text-green {
 @extend .text;
 color: green;
}

.textの内容を継承し、さらに色の設定を加えています。
各text-◯◯に.textの設定を共通で加えているようなイメージですよね。

しかしこれを出力すると以下のようになります。

extend css

.text, .text-red, .text-blue, .text-green {
 font-size: 14px;
 font-weight: 400
}

.text-red {
 color: red
}

.text-blue {
 color: blue
}

.text-green {
 color: green
}

共通化というにはいささかイメージが違いましたか?
後の比較のため、まずはこの形を覚えておきましょう。

ただこの形ですと.textは継承のためだけに使われているので余計な記述ですよね。そのため以下の様な記述を使います。

extend scss

%text {
 font-size: 14px;
 font-weight: 400;
}

.text-red {
 @extend %text;
 color: red;
}

.text-blue {
 @extend %text;
 color: blue;
}

.text-green {
 @extend %text;
 color: green;
}

%はプレースホルダーといって冒頭につけておけばこの記述をした物自体はcssとして出力されることはありません。

extend 出力css

.text-red, .text-blue, .text-green {
font-size: 14px;
font-weight: 400
}

.text-red {
color: red
}

.text-blue {
color: blue
}

.text-green {
color: green
}

こうなります。スッキリしますね。

include

includeはあらかじめ作成された関数を呼び出す指定です。
呼び出すには予めmixinで引き継ぐためのものを作っておく必要があります。

include Sass

@mixin text {
//予め共通項をつくっておく
font-size: 14px;
font-weight: 400;
}
.text-red {
@include text;
color: red;
}

.text-blue {
@include text;
color: blue;
}

.text-green {
@include text;
color: green;
}

そして出力されるcssは

include 出力css

.text-red {
font-size: 14px;
font-weight: 400;
color: red
}

.text-blue {
font-size: 14px;
font-weight: 400;
color: blue
}

.text-green {
font-size: 14px;
font-weight: 400;
color: green
}

こうなります。設定されている項目が追加される形です。わかりやすいですね。

include引数Ver

@mixin text($fz: 14px, $fw400) {
//引数を設定できる。「$引数:デフォルト値」で記載、複数記載可
font-size: $fz;
font-weight: $fw;
}
.text-red {
@include text;
color: red;
}

.text-blue {
@include text;
color: blue;
}

.text-green {
@include text(12,600);//12px、ウエイト600になる。
color: green;
}

さらにmixinの場合、引数を設定しておけます。
includeする際に数値を入れてあげればそのとおりに使い回せます。これも利点ですね。

extendとincludeの使い分け

これは僕流も入っていますが

「意味が同じくくり」であればextendが検証モードでもひとまとめになり、違いのある箇所だけが出てくるので管理しやすいです。
css的にも見やすい。対して

「単に共通な指定」をしたいのであればincludeにするといいです。たとえば

extendが適さない場合

%flex{
 display: flex;
 justify-content: center;
 align-items: center;
}

.div-flex{
 @extend %flex;
 width: 200px;
 height: 50px;
}

.btn{
 @extend %flex;
 padding: 5px;
 font-size: 14px;
}

これはレイアウトに使うものと、ボタンで中心に要素をもってきたいという指定ですが、こういうケースではextendは適しません
意味がぜんぜん違うのにcss上では共通項がひとくくりにされて出力されてしまうためです。

includeを使おう

@mixin flex{
 display: flex;
 justify-content: center;
 align-items: center;
}

.div-flex{
 @include flex;
 width: 200px;
 height: 50px;
}

.btn{
 @include flex;
 padding: 5px;
 font-size: 14px;
}

こういった「たまたま共通の指定がある」場合はincludeで対応しましょう。

まとめ

  • extendとincludeで迷うならincludeだけでもOK。
  • extendで適さない場合はあってもincludeでダメな場合はほぼない。
  • extendは同じくくりの中でひとまとめにする場合は便利。
  • includeは「たまたま指定が共通」な場合に適している。
  • includeは引数も使える。