:not()

:not() CSS 伪类 表示与选择器列表不匹配的元素。由于它阻止了特定项目的选中,因此被称为否定伪类

试一试

:not() 伪类有一些怪癖、技巧和意外结果,在使用之前应该了解。

语法

:not() 伪类需要一个选择器列表,一个用逗号分隔的一个或多个选择器的列表,作为其参数。列表中不能包含另一个否定选择器或伪元素,但允许任何其他简单、复合和复杂的选择器。

css
:not(<complex-selector-list>) {
  /* ... */
}

描述

使用 :not() 时,有一些不寻常的效果和结果需要牢记

  • 可以使用此伪类编写无用的选择器。例如,:not(*) 匹配任何不是元素的元素,这显然是无稽之谈,因此随附的规则永远不会被应用。
  • 此伪类可以增加规则的特异性。例如,#foo:not(#bar) 将匹配与更简单的 #foo 相同的元素,但具有两个 id 选择器更高的特异性。
  • :not() 伪类的特异性由其逗号分隔的选择器参数中最特定选择器的特异性代替;提供与已写入:not(:is(argument))相同特异性。
  • :not(.foo) 将匹配任何不是 .foo 的内容,包括<html><body>
  • 此选择器将匹配所有“不是 X”的内容。当与后代组合器一起使用时,这可能会令人惊讶,因为有多种路径可以选择目标元素。例如,body :not(table) a 仍然适用于 <table> 内部的链接,因为 <tr><tbody><th><td><caption> 等都可以匹配选择器的 :not(table) 部分。为避免这种情况,您可以改用 body a:not(table a),它仅适用于不是表格后代的链接。
  • 您可以同时否定多个选择器。例如::not(.foo, .bar) 等价于 :not(.foo):not(.bar)
  • 如果传递给 :not() 伪类的任何选择器无效或不受浏览器支持,则整个规则将失效。克服此行为的有效方法是使用 :is() 伪类,它接受一个宽容的选择器列表。例如 :not(.foo, :invalid-pseudo-class) 将使整个规则失效,但 :not(:is(.foo, :invalid-pseudo-class)) 将匹配任何(包括 <html><body>)不是 .foo 的元素。

示例

使用 :not() 和有效选择器

此示例显示了一些使用 :not() 的简单案例。

HTML

html
<p>I am a paragraph.</p>
<p class="fancy">I am so very fancy!</p>
<div>I am NOT a paragraph.</div>
<h2>
  <span class="foo">foo inside h2</span>
  <span class="bar">bar inside h2</span>
</h2>

CSS

css
.fancy {
  text-shadow: 2px 2px 3px gold;
}

/* <p> elements that don't have a class `.fancy` */
p:not(.fancy) {
  color: green;
}

/* Elements that are not <p> elements */
body :not(p) {
  text-decoration: underline;
}

/* Elements that are not <div>s or `.fancy` */
body :not(div):not(.fancy) {
  font-weight: bold;
}

/* Elements that are not <div>s or `.fancy` */
body :not(div, .fancy) {
  text-decoration: overline underline;
}

/* Elements inside an <h2> that aren't a <span> with a class of `.foo` */
h2 :not(span.foo) {
  color: red;
}

结果

使用 :not() 和无效选择器

此示例显示了使用 :not() 和无效选择器以及如何防止失效。

HTML

html
<p class="foo">I am a paragraph with .foo</p>
<p class="bar">I am a paragraph with .bar</p>
<div>I am a div without a class</div>
<div class="foo">I am a div with .foo</div>
<div class="bar">I am a div with .bar</div>
<div class="foo bar">I am a div with .foo and .bar</div>

CSS

css
/* Invalid rule, does nothing */
p:not(.foo, :invalid-pseudo-class) {
  color: red;
  font-style: italic;
}

/* Select all <p> elements without the `foo` class */
p:not(:is(.foo, :invalid-pseudo-class)) {
  color: green;
  border-top: dotted thin currentcolor;
}

/* Select all <div> elements without the `foo` or the `bar` class */
div:not(.foo, .bar) {
  color: red;
  font-style: italic;
}

/* Select all <div> elements without the `foo` or the `bar` class */
div:not(:is(.foo, .bar)) {
  border-bottom: dotted thin currentcolor;
}

结果

p:not(.foo, :invalid-pseudo-class) 规则无效,因为它包含无效的选择器。:is() 伪类接受一个宽容的选择器列表,因此 :is(.foo, :invalid-pseudo-class) 规则有效且等价于 :is(.foo)。因此,p:not(:is(.foo, :invalid-pseudo-class)) 规则有效且等价于 p:not(.foo)

如果 :invalid-pseudo-class 是一个有效的选择器,则上面前两个规则仍然等价(后两个规则展示了这一点)。使用 :is() 使规则更健壮。

规范

规范
选择器级别 4
# 否定

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅