:where()

Baseline 已广泛支持

此特性已得到良好确立,并可在多种设备和浏览器版本上运行。自 2021 年 1 月起,所有浏览器均已支持此特性。

:where() CSS 伪类函数接受一个选择器列表作为其参数,并选择可被该列表中任一选择器选中的任何元素。

:where():is() 的区别在于 :where() 始终具有 0 特异度,而 :is() 则采用其参数中最具体选择器的特异度。

试一试

ol {
  list-style-type: upper-alpha;
  color: darkblue;
}

/* Not applied to ol, because of lower specificity */
:where(ol, ul, menu:unsupported) :where(ol, ul) {
  color: green;
}

:where(ol, ul) :where(ol, ul) ol {
  list-style-type: lower-greek;
  color: chocolate;
}
<ol>
  <li>Saturn</li>
  <li>
    <ul>
      <li>Mimas</li>
      <li>Enceladus</li>
      <li>
        <ol>
          <li>Voyager</li>
          <li>Cassini</li>
        </ol>
      </li>
      <li>Tethys</li>
    </ul>
  </li>
  <li>Uranus</li>
  <li>
    <ol>
      <li>Titania</li>
      <li>Oberon</li>
    </ol>
  </li>
</ol>

语法

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

参数

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

宽容选择器解析

规范将 :is():where() 定义为接受宽容选择器列表

在 CSS 中使用选择器列表时,如果任何选择器无效,则整个列表被视为无效。而使用 :is():where() 时,如果其中一个选择器未能解析,则不会将整个选择器列表视为无效,而是忽略不正确或不受支持的选择器,并使用其他选择器。

css
:where(:valid, :unsupported) {
  /* … */
}

即使在不支持 :unsupported 的浏览器中,也会正确解析并匹配 :valid,而

css
:valid,
:unsupported {
  /* … */
}

即使支持 :valid,不支持 :unsupported 的浏览器也会忽略。

示例

比较 :where() 和 :is()

此示例演示了 :where() 的工作原理,并说明了 :where():is() 之间的区别。

以下面的 HTML 为例

html
<article>
  <h2>:is()-styled links</h2>
  <section class="is-styling">
    <p>
      Here is my main content. This
      <a href="https://mozilla.org">contains a link</a>.
    </p>
  </section>

  <aside class="is-styling">
    <p>
      Here is my aside content. This
      <a href="https://mdn.org.cn">also contains a link</a>.
    </p>
  </aside>

  <footer class="is-styling">
    <p>
      This is my footer, also containing
      <a href="https://github.com/mdn">a link</a>.
    </p>
  </footer>
</article>

<article>
  <h2>:where()-styled links</h2>
  <section class="where-styling">
    <p>
      Here is my main content. This
      <a href="https://mozilla.org">contains a link</a>.
    </p>
  </section>

  <aside class="where-styling">
    <p>
      Here is my aside content. This
      <a href="https://mdn.org.cn">also contains a link</a>.
    </p>
  </aside>

  <footer class="where-styling">
    <p>
      This is my footer, also containing
      <a href="https://github.com/mdn">a link</a>.
    </p>
  </footer>
</article>

在这个有些刻意的例子中,我们有两个文章,每个文章都包含一个 section、一个 aside 和一个 footer。它们的不同之处在于用于标记子元素的类。

为了对链接进行分组选择,同时保持 is-stylingwhere-styling 样式清晰,我们可以按以下方式使用 :is():where()

css
html {
  font-family: sans-serif;
  font-size: 150%;
}

:is(section.is-styling, aside.is-styling, footer.is-styling) a {
  color: red;
}

:where(section.where-styling, aside.where-styling, footer.where-styling) a {
  color: orange;
}

然而,如果我们以后想使用由低特异性类型选择器组成的复合选择器来覆盖页脚中链接的颜色,该怎么办?

css
footer a {
  color: blue;
}

这对于红色链接不起作用,因为 :is() 内部的选择器会计入整个选择器的特异性,并且类选择器比元素选择器具有更高的特异性。

然而,:where() 内部的选择器特异性为 0,因此橙色页脚链接将被我们的仅类型复合选择器覆盖。

注意:您也可以在 GitHub 上找到此示例;请参阅 is-where

规范

规范
选择器 Level 4
# 零匹配

浏览器兼容性

另见