特定の親要素を持つ子要素だけ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を当てない方法について考察してきました。デモページをご用意しましたので、ぜひ参考にしてください。
目的にあった手段をうまく選んでいきましょう。