SCSSを考える~@extendと@mixin~

SCSSにおける@extendと@mixinはどちらも「重複するコードをまとめる」ためのものです。
上手く使えば記述の省力化・改修時のミス防止に大きな成果をあげることができます。

この記事では@entendと@mixinの違いとその使い分けをまとめます。

@extend

@extendの意味は「継承」です。他のクラスの内容を受け継ぐことができます。

scss

//継承元
.btn {
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;

  //継承先
  &--primary {
    @extend .btn;
    background-color: red;
  }

  //継承先
  &--back {
    @extend .btn;
    background-color: gray;
  }
}

css

.btn, .btn--back, .btn--primary {
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;
}

.btn--primary {
  background-color: red;
}

.btn--back {
  background-color: gray;
}

なお、継承元のクラスにプレースホルダ(%)をつけると、そのクラスはコンパイルされません。

@mixin

@mixinも他クラスの「継承」を行う点では@extendと同じです。
@mixinは@extendより複雑な継承方法で、引数を使うことができます。
また、

  • 継承元のクラスは特殊な書き方をする
  • 継承元のクラスはコンパイルされない

という特徴があります。

scss

//継承元
@mixin btn ($bg-color: red){
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;
  background-color: $bg-color;
}

.btn {
  &--primary {
    //継承先
    @include btn();
  }

  &--back {
    //継承先
    @include btn($bg-color: gray);
  }
}

css

.btn--primary {
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;
  background-color: red;
}

.btn--back {
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;
  background-color: gray;
}

@extendと@mixinの使い分け

まず、引数を用いる場合は@mixinを使います。
そうでない場合、単純なコードの繰り返しならどうでしょうか?

コンパイル後のコードに注目してください。
@extendでは重複部分がひとつにまとめられていますが、@mixinではそれぞれのクラスに同じ記述が繰り返されています。
@extendのほうがコードが短くなる利点がありますが、多用すると以下のようになることがあります。

css


.prifile-name p,.news-list-title div,.map-detail-text.regular p,.map-detail-text.bold div,.map-detail-text.extra p,.company-name-01.profile div,.company-name-01.compact p,.company-02.company-name-01.compact div,.take-over-message-two p{
  font-size: 11px;
}

このようにセレクタが増えていくと、その分出力されたcssの解析・デバックなどが困難になってしまいます。
特にこの例で問題なのは、クラス名に規則性がないことです。

@extendを使う時は、クラス名の規則性を意識しながら使うと良いです。
既出の例では規則性があり、継承元・継承先のグループ関係がわかりやすいです。

//継承元
.btn {
  font-size: 1.6rem;
  width: 250px;
  height: 50px;
  border-radius: 5px;

  //継承先
  &--primary {
    @extend .btn;
    background-color: red;
  }

  //継承先
  &--back {
    @extend .btn;
    background-color: gray;
  }
}

以上の理由から、汎用性の高いクラスはたとえ引数を使わないケースであっても@mixinのほうが適していると考えます。
汎用性の高いクラスには以下のような特徴があります。

  • 複数の場所で横断的に利用する
  • それぞれのクラスに関連性がない

@extendのほうが使いどころが難しいので、迷ったら@mixinでいいかもしれません。

@extendと@mixinはなぜ生まれたのか

「extend」も「mixin」も、他のプログラミング言語に存在する概念です。
SCSSの@extend・@mixinは他プログラミング言語における「クラス」の継承システムを再現していると言えます。

注意するべき点は、プログラミング言語における「クラス」はCSSにおけるクラスとは異なる概念であり、一つずつ使うということです。
SCSSがシングルクラス運用と相性がいいのにはこうした理由があります。

CSSはHTMLを装飾するためのものですが、デザインが複雑化するにつれコードが長くなり、長期的に運用するのが難しくなってしまいました。
メンテナンス性の他、システムへ組み込む際に他言語のように構造化したいという要請もあり、SCSSが生まれました。
実際SCSSはかなりプログラマ目線で作られています。@mixinの見た目はほぼ関数ですね。
なのでプログラミング言語に触れたことがない場合は、一体なぜこんな機能があるのか、よくわからないこともあると思います(少なくとも私はそうでした)。

プログラミングの発想でCSSを拡張している、という点は意識しておいて良いと思います。

まとめ

繰り返しになりますが、そもそもSCSSを利用するメリットは

  • 記述の省力化
  • 改変時のミス防止

です。
同じ記述をできるだけまとめておくと、保守が楽になりますね。良いコーダーライフを!

スタッフ積極採用中

ジェイオンラインではスタッフを随時募集しております。
採用情報ページよりお気軽にお問い合わせください。

この記事を書いた人

有園菜希子
有園菜希子
フロントエンドエンジニアになりたいコーダー。