特定の親要素を持つ子要素だけcssを当てない方法
※本記事のコードは参考用です。使用前にご自身で動作確認をお願いします。
特定の親要素に基づいて、その子要素にスタイルを適用したくない場面はよくあります。
実際、このブログを作成する際、<pre>
タグ内の<code>
要素にはスタイルを適用したくない状況が出たので、それについての備忘録です。
:notセレクタを使った例
:not()
擬似クラスを使うと、特定の要素を除外してスタイルを適用することができます。
/* pre要素の外にあるcode要素だけにスタイルを適用する */
:not(pre) > code {
background-color: #f0f0f0;
padding: 0.2em 0.4em;
border-radius: 4px;
}
この方法では、「直近の親がpreではないcode」にだけスタイルが適用されます。
ポイントは、not(pre) > code
と子セレクタに指定することです。
なぜ:not(pre) codeではだめなのか?
pre
の中にあるcode
全てに適用したいから、:not(pre) code
だと思いがちですが、これだと意図しない挙動になってしまいます。
たとえば、以下のHTMLを見てください。
<div>
<pre>
<code>これはpre内のコードです</code>
</pre>
</div>
この場合、divはpreではないので、:not(pre)
にマッチしてしまい、divの中にあるcodeにスタイルが当たってしまいます。
つまり、たとえpre内にあるcodeだとしても、スタイルが適用されてしまい、「pre内のcodeにはスタイルを当てたくない」という目的とズレてしまいます。
all: unsetを利用した例
pre
は中にdivなどのブロック要素をいれることができませんが、例えば以下のようにcodeがpreの孫要素だとしてもスタイルを当てたくない場合、:not()
だと指定が難しいです。
<pre>
<span>
<code>これはpre内のコードです</code>
</span>
</pre>
:not()
セレクタでは「親がpreじゃない」ことしか見れないため、孫要素(間に何かが挟まっている場合)まで正確に除外するのは難しいです。
そのため、確実に「pre内のcodeにはスタイルを当てたくない」場合は、all: unset
を使う方法が有効です。
all: unset
は要素に適用されているすべてのスタイルをリセットするcssプロパティです。
code {
/* まずすべてのcodeにスタイルを適用 */
background-color: #f0f0f0;
padding: 0.2em 0.4em;
border-radius: 4px;
}
pre code {
all: unset; /* preの中にあるすべてのcodeはリセットする */
background-color: #000;
}
* 一旦code全部にスタイルを当てる
* そのあと、pre配下のcodeをリセットする
ただし、「親から継承されるはずのプロパティ」などもリセットされる強力なプロパティなので、使い所にはかなり注意が必要です。
## まとめ
以上、特定の親要素を持つ子要素だけcssを当てない方法について考察してきました。
デモページをご用意しましたので、ぜひ参考にしてください。
目的にあった手段をうまく選んでいきましょう。