:not()

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

:not() CSS 伪类表示不匹配选择器列表的元素。因为它阻止选择特定项,所以被称为否定伪类

试一试

p:not(.irrelevant) {
  font-weight: bold;
}

p > strong,
p > b.important {
  color: crimson;
}

p > :not(strong, b.important) {
  color: darkmagenta;
}
<p>
  <b>Mars</b> is one of the most Earth-like planets. <b>Mars</b> day is almost
  the same as an Earth day, only <strong>37 minutes</strong> longer.
</p>

<p class="irrelevant">
  <b class="important">NASA</b>'s Jet <del>Momentum</del> Propulsion Laboratory
  is designing mission concepts to survive the <b>Venus</b> extreme temperatures
  and atmospheric pressure.
</p>

:not() 伪类有许多怪癖、技巧和意想不到的结果,在使用它之前应该注意。

语法

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

参数

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

描述

在使用 :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() 使规则更健壮。

规范

规范
选择器 Level 4
# 否定

浏览器兼容性

另见