“not()选择器在Safari和Chrome/Firefox之间的行为不同”

13

我很难理解为什么下面的代码在Safari中是蓝色的,而在Chrome和Firefox中是红色的。

em:not(div) {
    color: red
}
em:not(p div) {
    color: blue
}
<p>
    <em>FOO</em>
</p>

https://jsfiddle.net/hzcLpf9L/

Chrome和Firefox似乎不支持带有多级别的:not() CSS选择器。(可能是个bug?)

我非常喜欢使用:not()选择器,并且在Safari上进行开发。因此,当我在Chrome上发现我的网站时,我几乎心脏病发作了。如果有任何关于为什么会出现这种奇怪行为的解释,我将不胜感激。


这不是一个 bug,只是一项他们尚未实现的新功能。 - TylerH
2个回答

16
Safari最近发布了级别4版本的:not(),允许使用复杂选择器作为参数,使其与jQuery迄今非标准实现相媲美。请查看发行说明当前版本的:not()只允许一个简单选择器作为参数,因此像p div这样的复杂选择器在当今的浏览器中不起作用是有意设计的。
一个复杂选择器是由一个或多个复合选择器组成的表达式,这些复合选择器由后代、>~+等组合器分隔。复合选择器是一个或多个简单选择器的序列。div是由一个简单选择器组成的复合选择器,p div是由两个复合选择器(每个复合选择器都由一个简单选择器组成)组成的复杂选择器,它们之间用一个后代组合器分隔。

目前尚不清楚这个功能何时会在其他浏览器中实现,但很可能新的:not()规范在这一点上不会改变——当前的4级定义是显而易见的,如果原始的WebKit分支足够大胆地实现它,那么它进入其他分支(包括Blink)只是时间问题。

自从FPWD以来,经过将近五年的漫长等待,我们可能真的很快就能看到选择器4的CR了。考虑到这一点,我感到很兴奋。


最新的Bootstrap中提取的以下表达式已经失效:.btn-group > .btn:not(:last-child):not(.dropdown-toggle), .btn-group > .btn-group:not(:last-child) > .btn { ...styles here... } - Brian Sweeney
@Brian Sweeney:抱歉,您能澄清一下吗?是在浏览器中出现问题还是Bootstrap的作者编写有误? - BoltClock
如果我理解你的回答,那么这不是应该出现在 Booststrap CSS 中的表达式,因为它不适用于所有浏览器。这有意义吗? - Brian Sweeney
@Brian Sweeney:这些选择器符合级别3,因为每个:not()只包含一个参数,并且与其相应的.btn或.btn-group类选择器链接在一起,没有组合器,这是与此处描述的问题不同的问题。 - BoltClock

6

来自规范

否定伪类 :not(X) 是一种函数表示法,它将一个简单选择器(不包括否定伪类本身)作为参数。它表示一个不被其参数所表示的元素。

以及规范中的其他地方

简单选择器可以是类型选择器、通用选择器、属性选择器、类选择器、ID 选择器或伪类。


Chrome 和 Firefox 的行为是正确的。后代组合器不能出现在简单选择器(因此也不能出现在 :not 伪类)中。


这可能会在选择器 Level 4 中改变。当前的编辑草案允许更复杂的选择器。你似乎遇到了一个实验性的实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接