为什么是我的jQuery:不()select器不工作在CSS?

我有这样的布局:

<div id="sectors"> <h1>Sectors</h1> <div id="s7-1103" class="alpha"></div> <div id="s8-1104" class="alpha"></div> <div id="s1-7605" class="beta"></div> <div id="s0-7479"></div> <div id="s2-6528" class="gamma"></div> <div id="s0-4444"></div> </div> 

有了这些CSS规则:

 #sectors { width: 584px; background-color: #ffd; margin: 1.5em; border: 4px dashed #000; padding: 16px; overflow: auto; } #sectors > h1 { font-size: 2em; font-weight: bold; text-align: center; } #sectors > div { float: left; position: relative; width: 180px; height: 240px; margin: 16px 0 0 16px; border-style: solid; border-width: 2px; } #sectors > div::after { display: block; position: absolute; width: 100%; bottom: 0; font-weight: bold; text-align: center; text-transform: capitalize; background-color: rgba(255, 255, 255, 0.8); border-top: 2px solid; content: attr(id) ' - ' attr(class); } #sectors > div:nth-of-type(3n+1) { margin-left: 0; } #sectors > div.alpha { color: #b00; background-color: #ffe0d9; } #sectors > div.beta { color: #05b; background-color: #c0edff; } #sectors > div.gamma { color: #362; background-color: #d4f6c3; } 

我使用jQuery将unassigned类添加到不具有alphabetagamma类之一的扇区:

 $('#sectors > div:not(.alpha, .beta, .gamma)').addClass('unassigned'); 

然后我对这个类应用一些不同的规则:

 #sectors > div.unassigned { color: #808080; background-color: #e9e9e9; opacity: 0.5; } #sectors > div.unassigned::after { content: attr(id) ' - Unassigned'; } #sectors > div.unassigned:hover { opacity: 1.0; } 

而且在现代浏览器中一切都完美无瑕。

互动jsFiddle预览

但是看到jQuery中的:not()select器是基于:not()在CSS3中 ,我想我可以直接将它移动到我的样式表中,所以我不必依赖使用jQuery添加额外的类。 另外,我并不是很喜欢支持IE的老版本,而其他的浏览器对:not()select器有很好的支持。

所以我尝试改变上面的.unassigned部分到这个(知道我将只有部门Α,Β和Γ在我的布局):

 #sectors > div:not(.alpha, .beta, .gamma) { color: #808080; background-color: #e9e9e9; opacity: 0.5; } #sectors > div:not(.alpha, .beta, .gamma)::after { content: attr(id) ' - Unassigned'; } #sectors > div:not(.alpha, .beta, .gamma):hover { opacity: 1.0; } 

但只要我这样做,它停止工作 – 在所有的浏览器 ! 我未分配的扇区不会变灰,淡出或标记为“未分配”。

更新但不是如此互动jsFiddle预览

为什么:not()select器在jQuery中工作,但在CSS中失败? 它应该不是在两个地方相同的工作,因为jQuery声称是“CSS3兼容”,或者有什么我失踪?

有没有一个纯粹的CSS解决方法,或者我将不得不依靠一个脚本?

为什么:not()select器在jQuery中工作,但在CSS中失败? 它应该不是在两个地方相同的工作,因为jQuery声称是“CSS3兼容”,或者有什么我失踪?

也许它应该 ,但事实certificate,它 :jQuery扩展了:not()select器,以便您可以传递任何select器到它 ,不pipe它可能有多复杂, 我怀疑这主要是因为与.not()方法进行奇偶校验,也相应地取任意复杂的select器和滤波器。 它以某种方式维护一个类似CSS的语法,但是它从标准中定义的内容扩展而来。

再举个例子,这个工作很好(我知道这个问题与问题中给出的相比是一个令人难以置信的荒谬的例子,但是这仅仅是为了说明的目的):

 /* * Select any section * that's neither a child of body with a class * nor a child of body having a descendant with a class. */ $('section:not(body > [class], body > :has([class]))') 

jsFiddle预览

请记住,将逗号分隔的select器列表传递给:not()表示过滤与列出的select器不匹配的元素。

现在,select器级别3中的:not()伪类本身非常有限。 您只能将一个简单的select器作为parameter passing给:not() 。 这意味着您一次只能通过其中的任何一个:

  • 通用select器( * ),可选地带有名称空间
  • typesselect器( adivspanulli等),可选地带有名称空间
  • 属性select器( [att][att=val]等),可选[att=val]有名称空间
  • 类select器( .class
  • IDselect器( #id
  • 伪类( :pseudo-class

所以,这里是jQuery之间的差异:not()select器和当前标准的:not()select器 :

  1. 首先,直接回答问题: 不能传递逗号分隔的select器列表。 1例如,虽然给出的select器在jQuery中演示,但它不是有效的CSS:

     /* If it's not in the Α, Β or Γ sectors, it's unassigned */ #sectors > div:not(.alpha, .beta, .gamma) 

    有没有一个纯粹的CSS解决方法,或者我将不得不依靠一个脚本?

    谢天谢地,在这种情况下, 您只需链接多个:not()select器,以使其成为有效的CSS:

     #sectors > div:not(.alpha):not(.beta):not(.gamma) 

    它不会使select器时间更长,但不一致和不便仍然很明显。

    更新了交互式jsFiddle预览

  2. 您不能将简单的select器合并到复合select器中,以用于:not() 这在jQuery中工作,但是无效的CSS:

     /* Do not find divs that have all three classes together */ #foo > div:not(.foo.bar.baz) 

    你需要把它分解成多个否定(而不是链接它们)来使其有效的CSS:

     #foo > div:not(.foo), #foo > div:not(.bar), #foo > div:not(.baz) 

    正如你所看到的,这比第一点更不方便。

  3. 你不能使用组合器。 这在jQuery中工作,但不是CSS:

     /* * Grab everything that is neither #foo itself nor within #foo. * Notice the descendant combinator (the space) between #foo and *. */ :not(#foo, #foo *) 

    这是一个特别恶劣的情况,主要是因为它没有适当的解决方法。 有一些松散的解决方法( 1和2 ),但它们几乎总是依赖于HTML结构,因此在实用性方面非常有限。

  4. 在实现querySelectorAll():not()select器的浏览器中,在select器string中使用:not()方法,使其成为一个有效的CSSselect器将导致该方法直接返回结果,而不是返回到Sizzle (实现了:not()扩展的jQueryselect器引擎)。 如果你是一个performance坚定的人,这是一个肯定微不足道的奖励,你一定会垂涎三尺。

好消息是, select器4增强了:not()select器以允许用逗号分隔的复杂select器列表。 一个复杂的select器就是一个简单的或复合select器,或者是由组合器分隔的整个复合select器链。 总之,你上面看到的一切。

这意味着上面的jQuery示例将成为有效的第4级select器,这将在CSS实现在未来几年开始支持伪类时更加有用。


1 虽然这篇文章说,你可以传递一个逗号分隔的select器列表:not()在Firefox 3中,你不应该能够。 如果这篇文章声称在Firefox 3中运行,那么这是因为Firefox 3中的一个错误,我无法再find该错误消息,但是直到将来的浏览器实现未来的标准之后,它才能正常工作。 看到这篇文章被引用到目前为止的频率,我已经留下了一个评论这个效果,但也看到多less年的文章,以及很less更新网站,我真的不指望作家回来修复它。