:is()

Baseline 已廣泛支援

此特性已得到良好確立,並可在多種裝置和瀏覽器版本上執行。自 2021 年 1 月起,所有瀏覽器均已支援此特性。

:is() CSS 偽類函式將一個選擇器列表作為其引數,並選擇可以由該列表中的任一選擇器選中的任何元素。這對於以更緊湊的形式編寫大型選擇器非常有用。

注意: 此選擇器最初命名為 :matches()(和 :any()),在 CSSWG issue #3258 中被重新命名為 :is()

試一試

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

:is(ol, ul, menu:unsupported) :is(ol, ul) {
  color: green;
}

:is(ol, ul) :is(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
:is(<forgiving-selector-list>) {
  /* ... */
}

引數

:is() 偽類需要一個選擇器列表,一個由逗號分隔的一個或多個選擇器作為其引數。該列表不能包含偽元素,但允許任何其他簡單選擇器、複合選擇器和複雜選擇器。

:is() 和 :where() 之間的區別

兩者的區別在於,:is() 會計入整個選擇器的特異性(它採用其最具體引數的特異性),而 :where() 的特異性值為 0。這在:where() 參考頁面上的示例中有所演示。

容錯選擇器解析

規範將 :is():where() 定義為接受容錯選擇器列表

在 CSS 中使用選擇器列表時,如果任何選擇器無效,則整個列表都被視為無效。當使用 :is():where() 時,如果其中一個選擇器無法解析,則不會將整個選擇器列表視為無效,而是會忽略不正確或不支援的選擇器,並使用其他選擇器。

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

即使在不支援 :unsupported 的瀏覽器中,它仍然可以正確解析並匹配 :valid,而

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

即使支援 :valid,在不支援 :unsupported 的瀏覽器中也會被忽略。

示例

簡化列表選擇器

:is() 偽類可以大大簡化你的 CSS 選擇器。例如,以下面的 CSS 為例

css
/* 3-deep (or more) unordered lists use a square */
ol ol ul,
ol ul ul,
ol menu ul,
ol dir ul,
ol ol menu,
ol ul menu,
ol menu menu,
ol dir menu,
ol ol dir,
ol ul dir,
ol menu dir,
ol dir dir,
ul ol ul,
ul ul ul,
ul menu ul,
ul dir ul,
ul ol menu,
ul ul menu,
ul menu menu,
ul dir menu,
ul ol dir,
ul ul dir,
ul menu dir,
ul dir dir,
menu ol ul,
menu ul ul,
menu menu ul,
menu dir ul,
menu ol menu,
menu ul menu,
menu menu menu,
menu dir menu,
menu ol dir,
menu ul dir,
menu menu dir,
menu dir dir,
dir ol ul,
dir ul ul,
dir menu ul,
dir dir ul,
dir ol menu,
dir ul menu,
dir menu menu,
dir dir menu,
dir ol dir,
dir ul dir,
dir menu dir,
dir dir dir {
  list-style-type: square;
}

你可以將其替換為

css
/* 3-deep (or more) unordered lists use a square */
:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) :is(ul, menu, dir) {
  list-style-type: square;
}

簡化區塊選擇器

:is() 偽類在處理 HTML 區塊和標題時特別有用。由於 <section><article><aside><nav> 通常是巢狀在一起的,如果沒有 :is(),將它們樣式化以相互匹配可能會很棘手。

例如,如果沒有 :is(),樣式化不同深度的所有 h1 元素可能會非常複雜

css
/* Level 0 */
h1 {
  font-size: 30px;
}

/* Level 1 */
section h1,
article h1,
aside h1,
nav h1 {
  font-size: 25px;
}

/* Level 2 */
section section h1,
section article h1,
section aside h1,
section nav h1,
article section h1,
article article h1,
article aside h1,
article nav h1,
aside section h1,
aside article h1,
aside aside h1,
aside nav h1,
nav section h1,
nav article h1,
nav aside h1,
nav nav h1 {
  font-size: 20px;
}

/* Level 3 */
/* don't even think about it! */

然而,使用 :is() 會容易得多

css
/* Level 0 */
h1 {
  font-size: 30px;
}
/* Level 1 */
:is(section, article, aside, nav) h1 {
  font-size: 25px;
}
/* Level 2 */
:is(section, article, aside, nav) :is(section, article, aside, nav) h1 {
  font-size: 20px;
}
/* Level 3 */
:is(section, article, aside, nav)
  :is(section, article, aside, nav)
  :is(section, article, aside, nav)
  h1 {
  font-size: 15px;
}

:is() 不選擇偽元素

:is() 偽類不匹配偽元素。所以,不要這樣寫

css
some-element:is(::before, ::after) {
  display: block;
}

或者這樣寫

css
:is(some-element::before, some-element::after) {
  display: block;
}

而是這樣寫

css
some-element::before,
some-element::after {
  display: block;
}

規範

規範
選擇器 Level 4
# 匹配偽元素

瀏覽器相容性

另見