@extendを使いこなすために

Blog

みなさまこんにちは。コーダーのtabataです。
最近、Sassの@extendを学びまして、便利だなあと使用しております。
が、しかし。
コンパイルされたcssを確認して思わず、うわ??となったことがありましたので、
その問題と解決法を書き留めておきたいと思います。

@extend って何ができるの?

まず、@extendの基本知識に関して説明します。
@extendを使うとスタイルの継承をすることができます。
例えば、同じボタンでもいくつかのカラー展開が存在することってありますよね。
下記のようなhtmlにスタイルを当てる際、@extendを使用すると.btnのスタイルを継承しつつ、
.btn-blueの背景色を青にすることができます。

<div>
    <button class="btn" type="submit">ボタン</button>
    <button class="btn-blue" type="submit">ボタン</button>
</div>
.btn {
    width: 150px;
    height: 40px;
    display: inline-block;
    background-color: tomato;
    color: #fff;
}
.btn-blue {
    @extend .btn;
    background-color: blue;
}

@extend の問題点

上記で@extendの良いところをお分りいただけたかと思います。
私もこれ便利だなあと思って使っていたのですが、多用しすぎるあまりよくないことが起こってしまいます。
例えば、先ほどのボタンのカラー展開が5色となり、下記のようにスタイルを指定したとします。

.btn {
    width: 150px;
    height: 40px;
    display: inline-block;
    background-color: tomato;
    color: #fff;
}
.btn-blue {
    @extend .btn;
    background-color: blue;
}
.btn-orange {
    @extend .btn;
    background-color: orange;
}
.btn-green {
    @extend .btn;
    background-color: green;
}
.btn-violet {
    @extend .btn;
    background-color: violet;
}

ここまでは良いのです。
しかし、コンパイルされたcssを見てみると。。。

.btn, .btn-tomato, .btn-blue, .btn-orange, .btn-green, .btn-violet {
    display: inline-block;
    width: 150px;
    height: 40px;
    background-color: tomato;
    color: #fff;
}
.btn-blue {
    background-color: blue;
}
.btn-orange {
    background-color: orange;
}
.btn-green {
    background-color: green;
}
.btn-violet {
    background-color: violet;
}

上記のようにセレクタがたくさん並び、見づらくなってしまうのです。
この程度なら問題ないだろうと思うかもしれませんが、問題なのがこちら↓

.p-business .p-business-nav__item .txt,
.p-business .p-business-nav__item .p-sc-01 .p-drawing__item .txt-up,
.p-sc-01 .p-drawing__item .p-business .p-business-nav__item .txt-up,
.p-business .p-business-nav__item .p-sc-01 .p-drawing__item .txt-down,
.p-sc-01 .p-drawing__item .p-business .p-business-nav__item .txt-down,
.p-business .p-business-nav__item .p-sc-01 .p-drawing__effect .txt-up,
.p-sc-01 .p-drawing__effect .p-business .p-business-nav__item .txt-up,
.p-business .p-business-nav__item .p-sc-01 .p-drawing__effect .txt-down,
.p-sc-01 .p-drawing__effect .p-business .p-business-nav__item .txt-down,
.p-business .p-business-nav__item .p-sc-02 .p-drawing__item .txt-up,
.p-sc-02 .p-drawing__item .p-business .p-business-nav__item .txt-up,
.p-business .p-business-nav__item .p-sc-02 .p-drawing__item .txt-down,
.p-sc-02 .p-drawing__item .p-business .p-business-nav__item .txt-down,
.p-business .p-business-nav__item .p-sc-02 .p-drawing__effect .txt-up,
.p-sc-02 .p-drawing__effect .p-business .p-business-nav__item .txt-up,
.p-business .p-business-nav__item .p-sc-02 .p-drawing__effect .txt-down,
.p-sc-02 .p-drawing__effect .p-business .p-business-nav__item .txt-down,
.p-business .p-business-nav__item .p-sc-03 .p-drawing .txt-up,
.p-sc-03 .p-drawing .p-business .p-business-nav__item .txt-up,
.p-business .p-business-nav__item .p-sc-03 .p-drawing .txt-down,
.p-sc-03 .p-drawing .p-business .p-business-nav__item .txt-down {
    padding-top: 22px;
    color: #fff;
    font-size: 18px;
    font-size: 1.125rem;
    line-height: 1;
}

ひどいですね。一瞬何が起きたんだろうと不安になってします。
偶然にもスタイルを共有しているからか、
他のページのスタイルまで無理やりグルーピングされてしまっています。
詳細度に関してもめちゃめちゃです。

解決法

上記の問題を解決する方法は主にこちらです。

  • @extendは使わずに、@mixinを使う。
  • 明確に関連しているルールセット同士で使用する。
  • プレースホルダーセレクタを使用する。

3つ目に関して少し説明すると、@extendしたいスタイルの先頭に%を付けることで、
無駄なセレクタの出力を防ぐことができます。

    %btn {
        width: 150px;
        height: 40px;
        display: inline-block;
        background-color: tomato;
        color: #fff;
    }
    .btn {
        @extend %btn;
    }
    .btn-blue {
        @extend %btn;
        background-color: blue;
    }

まとめ

今回のことで色々調べてみて、@extendはあまり好まれていない・そもそも使用しない
という人が多いようでした。
しかし、個人的には使いやすさを感じるので、
@extendと@mixinをうまく使い分けながら今後も使用していきたいと思います。

参考記事:https://postd.cc/when-to-use-extend-when-to-use-a-mixin/