我有这个布局:
<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
类添加到没有其中一个类alpha
,beta
或gamma
的扇区中:
$('#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;
}
现代浏览器中的一切都完美无瑕。
但看到:not()
selector in jQuery基于:not()
in CSS3,我认为我可以直接将其移动到我的样式表中,因此我不必依赖于使用jQuery添加额外的类。此外,我对支持旧版本的IE并不感兴趣,而其他浏览器也非常支持:not()
选择器。
所以我尝试将上面的.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;
}
但是一旦我这样做就会停止工作 - 在所有浏览器中!我未分配的扇区不会变灰,淡出或标记为“未分配”。
Updated but not so interactive jsFiddle preview
为什么:not()
选择器在jQuery中工作但在CSS中失败?它不应该在两个地方都相同,因为jQuery声称是“符合CSS3”,或者是否有一些我缺少的东西?
是否有纯粹的CSS解决方法或者我必须依赖脚本吗?
答案 0 :(得分:78)
为什么
:not()
选择器在jQuery中工作但在CSS中失败?它不应该在两个地方都相同,因为jQuery声称是“符合CSS3”,或者是否有一些我缺少的东西?
也许应该,但事实证明它不:jQuery扩展了:not()
选择器,使得you can pass any selector to it,无论如何它有多复杂,而且我怀疑这个的主要原因是.not()
method与jsFiddle preview的奇偶校验,它也相应地采用任意复杂的选择器和过滤器。它确实维护了类似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]))')
:not()
pseudo-class in Selectors level 3
请记住,将逗号分隔的选择器列表传递给:not()
意味着过滤与任何列出的选择器不匹配的元素。
另一方面,namespace本身非常有限。您只能将单个简单选择器作为参数传递给:not()
。这意味着您一次只能传递其中任何一个:
*
),可选择namespace a
,div
,span
,ul
,li
等),可选择namespace [att]
,[att=val]
等),可选择jQuery's :not()
selector .class
)#id
):pseudo-class
)因此,以下是the current standard's :not()
selector和Updated interactive jsFiddle preview之间的差异:
首先,要直接回答这个问题:你不能传递逗号分隔的选择列表。 1 例如,当给定选择器时在jQuery中工作,如小提琴中所示,它不是有效的CSS:
/* If it's not in the Α, Β or Γ sectors, it's unassigned */
#sectors > div:not(.alpha, .beta, .gamma)
是否有纯粹的CSS解决方法或者我必须依赖脚本吗?
谢天谢地,在这种情况下,有。您只需要依次链接多个:not()
选择器,以使其成为有效的CSS:
#sectors > div:not(.alpha):not(.beta):not(.gamma)
它不会使选择 更长,但不一致和不便仍然很明显。
您无法将简单选择器组合到复合选择器中以与: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)
如您所见,这比第1点更不方便。
你不能使用组合器。这适用于jQuery,但不适用于CSS:
/*
* Grab everything that is neither #foo itself nor within #foo.
* Notice the descendant combinator (the space) between #foo and *.
*/
:not(#foo, #foo *)
这是一个特别令人讨厌的案例,主要是因为它没有适当的解决方法。有一些松散的变通办法(2和Selectors 4 enhances the :not()
selector),但它们几乎总是依赖于HTML结构,因此实用性非常有限。
在实现querySelectorAll()
和:not()
选择器的浏览器中,在选择器字符串中使用:not()
以使其成为有效的CSS选择器的方式将导致该方法直接返回结果,而不是回到Sizzle(jQuery的实现:not()
扩展名的选择器引擎)。如果你是表演者的坚持者,那么这肯定是一个非常小的奖励,你肯定会垂涎三尺。
好消息是this article允许以逗号分隔的复杂选择器列表。复合选择器既可以是单独的简单选择器,也可以是复合选择器,也可以是由组合器分隔的整个复合选择器链。简而言之,你在上面看到的一切。
这意味着上面的jQuery示例将成为有效的4级选择器,这将使CSS类在未来几年开始支持时更加有用。
1 虽然comment表示您可以在Firefox 3中将逗号分隔的选择器列表传递给:not()
,但您不应该能够至。如果它在Firefox 3中可行,正如该文章所声称的那样,那是因为Firefox 3中的一个错误,我找不到它的故障了,但是在未来的浏览器实现未来的标准之前它不应该工作。看到这篇文章到目前为止被引用的频率,我已经留下了{{3}}这个效果,但是看到文章的年龄和网站的更新频率,我真的不指望作者回来解决它。