:not(.parent) > .target
:not
を親/先祖に対して使う
タイトルの通り、「親/先祖が〜〜でない」要素を示すCSSを:not
を使用して書く。
まず以下のようなHTML/CSSがあるとする。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
:not(.parent) > .target {
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="parent">親
<div class="target">親の中にいる</div>
</div>
<div class="target">親の中にいない</div>
</body>
</html>
親の中にいるdiv
の背景は塗られず、親の中にいないdiv
の背景だけが塗られることになる
See the Pen parent_not by shinkats (@shinkats) on CodePen.
:not(.parent) > .target
で:not
を使って「親が〜〜でない」要素のみを指定できていることがわかる。
:not
== *:not
このときの:not
部分に着目すると、:
の前に何も記載されていないため、:not
は*:not
と同じになる。
つまり:not(.parent)
はdiv:not(.parent)
でもあるし、body:not(.parent)
でもある。そのため>
の有無で結果が変わってしまう。
子セレクタ>
ではなく子孫セレクタの場合
親の中にいるdiv
は<div class="parent">
の子であると同時に、body
の子孫でもある。そのため、子セレクタをつけずに:not(.parent) .target
とすると、.parent
でないbody
の子孫である.target
という条件に合致し、背景が塗られる。
See the Pen Untitled by shinkats (@shinkats) on CodePen.
常に子セレクタ>
を使用して:not
を使用するようにする。
.target:not()
:not
を対象(子)自体につける
先ほどは:not
を*:not(.parent)
と親/先祖に対して指定していた。しかし、.target:not
と対象(子)自体を否定することでも「親/先祖が〜〜でない」要素を示すCSSを書くことができる。
この場合、子セレクタ>
の有無で挙動が致命的に変わりはしない。なぜなら*:not
と違って.target:not
であれば、.target
自体にはじめに絞っているから。div:not
のつもりで指定したものがbody:not
にまで効いているというようなことはおきない。
.target:not(.parent > .target)
.target:not(.parent > .target)
と書くことで、.parent
の子に.target
が続かない.target
という指定の仕方ができる。
つまり今回のHTMLで言うと、親の中にいないdiv
のみが対象になる。
.target:not(.parent .target)
.target:not(.parent .target)
と書くことで、.parent
の子孫に.target
がない.target
という指定の仕方ができる。
HTML次第では意図しない状況になる可能性もあるが、今回の場合は問題ないし、大概のケースで問題なく動くだろう。
とはいえ、子セレクタで明確に指定できる場合は子セレクタで明確に指定した方が良い。