
Sassで登場する@extendの活用方法と@mixinとの使い分け
CSSの拡張メタ言語であるSassにはいろんな便利機能が用意されています。その中でも「@extend」は少しマイナーなものであまり使われていない印象があります。Sassを普段からよく使う方でも実際にどういったものかよくわからないというのも多いのではないでしょうか。そこで今回は@extendの活用方法と、よく似ていると言われている@mixinとの使い分けの場面についてまとめていきたいと思います。
@mixinについて詳しくはこちらの記事「Sassのよく使う基本機能まとめ」でも紹介していますのでご参考に。@mixinで定義したものを@includeを使って任意の場所で呼び出すという形になります。
このように@extendと@mixinでは、似ているものの微妙に違いがありますね。どちらも定義したものを呼び出せるという部分は同じですが、呼び出せる内容が、@extendはスタイルのみなのに関して、@mixinではスタイルはもちろんのこと、いろんな処理を加えることもできるようになります。ちなみに、@mixinに関してはこれまでもいろんな記事をあげていますので、具体的な使い方についてはこちらをご参考ください。
(参考記事)
・Sassのmixinで引数と@ifを使った条件分岐のテクニック
・変数とmixinを使ったメディアクエリで効率的なレスポンシブコーディング
・マスクアニメーションを使ってカッコよく画像やテキストを表示させる
・Sassのマップ変数を活用して複雑なメディアクエリを一括で管理する
・Sassでクロスフェードのスライドアニメーションを実装する
・Sassでmarqueeタグのようなテキストを自動で流すループアニメーションを実装する
・Sassでパターン背景をスクロールさせるループアニメーションを実装する
ここで重要となるのが@mixinでは引数が使えるなど拡張性と柔軟性の高い点がポイントです。引数に入れた値をプロパティの変数値として、また引数の値を使って@ifでの条件分岐なども可能になります。@contentを組み合わせることで、呼び出し先で書いたスタイルを、@mixinで定義した処理の中に入れることもできます。ですので、@mixinは@extendの上位互換のようなものと言っても概ね間違いでは無いかと思います。
また、SASS記法の場合には「@mixin → =」と「@include → +」のように省略して記述することができますので、こちらも大きなメリットと言えますね。したがって、@extendと使い分けて共存させるよりも@mixinだけで統一するのもコーディングのルールとしては有りなのではないでしょうか。
ただ、@mixinの場合にはプログラミングっぽい処理が使われることが多いため、コードを読むのが難しくなる場合もあります。@extendの場合には単純に継承元のclassで適用させたスタイルを引き継ぐのでシンプルに使うことができるので、そういったときの選択肢としてはいいですね。ちなみに返すものがスタイルではなく、単純に値のみの場合には@mixinより@functionの方がスマートですね。
今回はSassで使う@extendについて詳しく触れてみました。正直なところこれまであまり使う場面がなく、ほとんど@mixinでの対応で済ませていましたが、@extendもプロジェクトの仕様や要件によっては@mixinより適しているということもあるかと思いますので、しっかり理解した上で使い分けれるようにしたいものですね。
指定したclassが持つスタイルを継承できる「@extend」
@extendは継承という機能で、あるclassに設定したスタイルを丸ごと、@extendを使って該当するclassを指定することで引き継ぐことができます。つまりclass単位でのスタイルのモジュール化が可能になります。実際にはSass側で下記のように継承用のclassを定義し、適用させたい要素の中で、@extendを使って呼び出すような形で記述します。 【Sass(SCSS)】.text-style {
font-size: 2em;
font-weight: bold;
color: red;
}
p {
@extend .text-style;
margin: 0 0 15px 0;
}
このようにしてCSSに変換すると、下記のように呼び出した要素は@extendで指定したclassが持つスタイルを継承することができます。
【CSS】
.text-style, p {
font-size: 2em;
font-weight: bold;
color: red;
}
p {
margin: 0 0 15px 0;
}
ですので、決まったスタイルであれば継承することで上手く使い回せるようになり、修正などが発生した場合のコストを抑えられることが期待できます。この辺りが@mixinと似ているためすこしややこしいと思われるポイントかもしれませんね。
@extendを使う上での注意点
ただし、便利そうな@extendも使う場合には少し注意点が必要です。それは継承したclassがセレクタとして適用した要素、あるいはセレクタにグルーピングされるという点です。例えば下記のように@extendで継承させるためのclassを複数書いていたとします。 【Sass(SCSS)】// @extendで継承用のclass
.button-primary {
background: blue;
box-shadow: 0 5px 0 darkblue;
}
.button-secondary {
background: green;
box-shadow: 0 5px 0 darkgreen;
}
.button-accent {
background: red;
box-shadow: 0 5px 0 darkred;
}
// @extendを適用
button {
color: white;
&:nth-child(1) {
@extend .button-primary;
padding: 10px;
}
&:nth-child(2) {
@extend .button-secondary;
padding: 5px 20px;
}
&:nth-child(3) {
@extend .button-accent;
padding: 10px 30px;
}
}
これを適用させる要素の指定で呼び出し、先ほどのclassを継承させるようにしておきます。この形でCSSにコンパイルすると実際のコードは下記のように、継承元のセレクタも追加されてスタイルとして適用されるようになります。
【CSS】
.button-primary, button:nth-child(1) {
background: blue;
box-shadow: 0 5px 0 darkblue;
}
.button-secondary, button:nth-child(2) {
background: green;
box-shadow: 0 5px 0 darkgreen;
}
.button-accent, button:nth-child(3) {
background: red;
box-shadow: 0 5px 0 darkred;
}
button {
color: white;
}
button:nth-child(1) {
padding: 10px;
}
button:nth-child(2) {
padding: 5px 20px;
}
button:nth-child(3) {
padding: 10px 30px;
}
本来は継承用のclassの特定の要素に対してセレクタとして含まれる必要はありません。なぜなら継承先のセレクタですでに同じスタイルが適用されているからです。ですので、この表記は無駄になりますし、仮にたくさんの継承元から呼び出している場合はセレクタ自体もかなり長くなってしまいます。
そこで、@extendで継承するclassに関しては「プレースホルダーセレクタ」と呼ばれる形式にします。これは、classを表すドットの代わりに「%」をつける形になります。
【Sass(SCSS)】
// @extendで継承用のclass
%button-primary {
background: blue;
box-shadow: 0 5px 0 darkblue;
}
%button-secondary {
background: green;
box-shadow: 0 5px 0 darkgreen;
}
%button-accent {
background: red;
box-shadow: 0 5px 0 darkred;
}
// @extendを適用
button {
color: white;
&:nth-child(1) {
@extend %button-primary;
padding: 10px;
}
&:nth-child(2) {
@extend %button-secondary;
padding: 5px 20px;
}
&:nth-child(3) {
@extend %button-accent;
padding: 10px 30px;
}
}
この場合に注意する点として、定義するときも呼び出すときも両方プレースホルダーを使った書き方で揃えるようにしましょう。これでコンパイルして実際にCSSを見てみると、先ほどの継承用のclass名が消えているのがわかります。
【CSS】※一部抜粋
button:nth-child(1) {
background: blue;
box-shadow: 0 5px 0 darkblue;
}
button:nth-child(2) {
background: green;
box-shadow: 0 5px 0 darkgreen;
}
button:nth-child(3) {
background: red;
box-shadow: 0 5px 0 darkred;
}
........
このように@extendを使う場合には、プレースホルダーセレクタとして扱うことで不要なclass名を削除することができます。「%」を使うことで、継承させるclassであることも明示できますので、これは@extendを使う上でのお作法として覚えておいても問題ないかと思います。
@extendと@mixinのそれぞれの使いどころ
これまで@extendについてその機能を詳しく見てきましたが、@mixinでも同じようなことが実現できます。@extendと@mixinの特徴をまとめてみると下記のようになります。| @extend | 定義したclassを他のclassにスタイルを継承できる |
|---|---|
| @mixin | 特定のスタイルや処理を@includeを使って任意の場所で呼び出せる |
今回はSassで使う@extendについて詳しく触れてみました。正直なところこれまであまり使う場面がなく、ほとんど@mixinでの対応で済ませていましたが、@extendもプロジェクトの仕様や要件によっては@mixinより適しているということもあるかと思いますので、しっかり理解した上で使い分けれるようにしたいものですね。
categories
- WordPress(61)
- JavaScript(49)
- Vue.js(48)
- CSS(46)
- jQuery(34)
- Nuxt.js(22)
- Sass(21)
- Gulp(17)
- webpack(16)
- PHP(14)
- HTML(14)
- GSAP(11)
- React(10)
- Vite(9)
- Pug(9)
- Laravel(8)
- Cordova(8)
- Linux(7)
- Next.js(6)
- Apache(5)
- Shopify(4)
- REST API(4)
- Node.js(4)
- Smarty(3)
- Git(3)
- JSON(3)
- その他プログラミング(3)
- Google Apps API(3)
- Bootstrap(3)
- 環境構築・システム(3)
- TypeScript(2)
- EJS(2)
- RMS(2)
- Docker(2)
- Instagram API(2)
- Excel VBA(2)
- SVG(1)
- Dart(1)
- ECカートASP(1)
- Markdown(1)
- AMP(1)
- Nginx(1)
- XML(1)
- shellscript(1)
- Ruby(1)
- MySQL(1)