否定擬似クラス :not の奇妙な挙動について

2015年10月30日 18:19

投げかけた疑問に答を出すべく、実際に試してみた。

<div class="hoge">
    <ul>
        <li>ほげほげ</li>
    </ul>
</div>
<div class="fuga">
    <ul>
        <li>ふがふが</li>
    </ul>
</div>
:not(.hoge) ul li:hover {
    color: red;
}

これで li のブロックにカーソルを合わせた場合、「ふがふが」のみ赤くなると思いきや、実際には「ほげほげ」も赤くなる。CSS の書き方が間違っていて構文自体が invalid になってしまっているのかなとも思ったが、それだと逆にどちらも赤くならないはずである。

否定擬似クラスと呼ばれる E:not(X) は、引数 X が単純セレクタでなければならない(つまり、連結したり複数指定はできない)ことと、他の否定クラスや擬似要素を含むことができないこと以外には大きな制約はない。そして、E は省略が可能である。つまり、考え得る限り、上記の指定は間違っていないと思うのだが……。

その後、あれこれ試してみて分かったのは、CSS を以下のように書けば思い通りの挙動になることだ。

div:not(.hoge) ul li:hover {
    color: red;
}

なんだ、E を省略したのがいけなかったのか、と一瞬納得しかけたのだが、じつは以下の記述でも大丈夫だった。

:not(.hoge) > ul li:hover {
    color: red;
}

うーん、明確な答には至らなかったか。引き続き調べてみようと思う。