はじめに
皆さん、CSSやSCSSなどでコーディングしているとき、「セレクタの詳細度」を意識していますでしょうか?
私は全く意識せずにSCSSのネスト機能を使いまくっていたら困ったことになり、原因はセレクタの詳細度をガン無視していたことでした。
セレクタの詳細度とは?
セレクタが競合した時にどのセレクタを適用するか、という「優先順位」を決めるための数値のこと。
「idはclassよりも優先順位が高い」「!importantを付ければ間違いない」とはよく聞きます。
そしてセレクタは一つ指定するよりも二つ指定する方が優先順位は高くなります。
例えば、
<div class="test1 test2"></div>
.test1.test2 {
width: 300px;
height: 300px;
margin-top: 50px;
background-color: red;
}
.test1 {
width: 300px;
height: 300px;
margin-top: 50px;
background-color: blue;
}
というファイルがあり、通常は後に書いたbackground-color: blue;
が適用されるが、セレクタを二つ指定する方が優先順位が高いため、background-color: red;
の方が適用される。
参考:
本題
SCSSにはネスト機能がありますが、上記で説明した通り、ネストすればするほどセレクタの詳細度は上がっていきます。
それが時に意図しない挙動の原因になる可能性を生む可能性があります。
例えば以下ののコードがあります。
<body>
<div class="wrapper">
<div class="box"></div>
</div>
</body>
.wrapper {
width: 100%;
.box {
width: 300px;
height: 300px;
background-color: blue;
margin: 50px auto 0;
}
}
@media (max-width: 600px) {
.box {
background-color: red;
}
}
上記は、青い要素を、@media (max-width: 600px)
で画面が600px以下になると赤色にしようとしています。
しかしこのままでは600px以下でも赤にはなりません。
なぜなら、セレクターの詳細度が違うからです。
コンパイルすると以下のようになります。
.wrapper {
width: 100%;
}
.wrapper .box {
width: 300px;
height: 300px;
background-color: blue;
margin: 50px auto 0;
}
@media (max-width: 600px) {
.box {
background-color: red;
}
ここで、最初に説明しました「セレクターは一つより二つ指定する方が詳細度が上がり、優先順位が高くなる。」が出てきます。
.box
より.wrapper .box
の方が優先順位が高くなるため、色が変わらなかったのです。
ではどうすればいいのかと言えば簡単で、優先順位が同じになるようにします。
.wrapper {
width: 100%;
}
.box {
width: 300px;
height: 300px;
background-color: blue;
margin: 50px auto 0;
}
@media (max-width: 600px) {
.box {
background-color: red;
}
}
もしくは
.wrapper {
width: 100%;
.box {
width: 300px;
height: 300px;
background-color: blue;
margin: 50px auto 0;
}
}
@media (max-width: 600px) {
.wrapper {
.box {
background-color: red;
}
}
}
このようにすれば優先順位が同じになり、意図した通りの挙動になります。
終わりに
ネストできるとこはとりあえずネスト!、と思いネストしまくったら痛い目に遭いました。
よく考えずに書いても動くことが多いため、気にしたことがなかったのですが、これからは頭の隅に置きながらやろうと思いました...。
参考サイト