:is() (:matches(), :any())

これは実験的な機能です。本番で使用する前にブラウザー実装状況をチェックしてください。

メモ: :matches():is() に改名されました。(CSSWG issue #3258)

CSS:is() 疑似クラス関数は、セレクターのリストを引数に取り、リスト中のセレクターの何れか一つに当てはまる要素をすべて選択します。数多くのセレクターを小さくまとめて書くのに便利です。

なお、現在のところ、ブラウザーはこの機能を :matches() として、または古いバージョンの Chrome、Firefox、Safari では、さらに古い接頭辞付きの疑似クラス :any() として対応しています。:any() は、:matches()/:is() とまったく同じものとして動作しますが、ベンダー接頭辞が必要であり、複合セレクターに対応していません。

/* header、main、footer 要素の中の段落で
   マウスポインターが通過中のものをすべて選択 */
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

/* 上記のものは以下と同じ */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}

/* -*-any() および :matches() と後方互換性のあるバージョン
   (無効なセレクターがあるとルール全体が無効になるため、
   セレクターを単一のルールにグループ化することはできません。) */
:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

構文

:is( <complex-selector-list> )

where
<complex-selector-list> = <complex-selector>#

where
<complex-selector> = <compound-selector> [ <combinator>? <compound-selector> ]*

where
<compound-selector> = [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!
<combinator> = '>' | '+' | '~' | [ '||' ]

where
<type-selector> = <wq-name> | <ns-prefix>? '*'
<subclass-selector> = <id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>
<pseudo-element-selector> = ':' <pseudo-class-selector>
<pseudo-class-selector> = ':' <ident-token> | ':' <function-token> <any-value> ')'

where
<wq-name> = <ns-prefix>? <ident-token>
<ns-prefix> = [ <ident-token> | '*' ]? |
<id-selector> = <hash-token>
<class-selector> = '.' <ident-token>
<attribute-selector> = '[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'

where
<attr-matcher> = [ '~' | | | '^' | '$' | '*' ]? '='
<attr-modifier> = i | s

クロスブラウザーの例

<header>
  <p>This is my header paragraph</p>
</header>

<main>
  <ul>
    <li><p>This is my first</p><p>list item</p></li>
    <li><p>This is my second</p><p>list item</p></li>
  </ul>
</main>

<footer>
  <p>This is my footer paragraph</p>
</footer>
:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
let matchedItems;

try {
  matchedItems = document.querySelectorAll(':is(header, main, footer) p');
} catch(e) {
  try {
    matchedItems = document.querySelectorAll(':matches(header, main, footer) p');
  } catch(e) {
    try {
      matchedItems = document.querySelectorAll(':-webkit-any(header, main, footer) p');
    } catch(e) {
      try {
        matchedItems = document.querySelectorAll(':-moz-any(header, main, footer) p');
      } catch(e) {
        console.log('Your browser doesn\'t support :is(), :matches(), or :any()');
      }
    }
  }
}

matchedItems.forEach(applyHandler);

function applyHandler(elem) {
  elem.addEventListener('click', function(e) {
    alert('This paragraph is inside a ' + e.target.parentNode.nodeName);
  });
}

リストセレクターの簡略化

:is() 疑似クラスは CSS セレクターをとても簡潔にすることができます。例えば以下の CSS の場合、

/* 3 層 (以上) の順序なしリストに四角形を使用 */
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;
}

... これを次のように置き換えることができます。

/* 3 層 (以上) の順序なしリストに四角形を使用 */
:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) ul,
:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) menu,
:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) dir {
  list-style-type: square;
}

section セレクターの簡略化

:is() 疑似クラスは、 HTML5 のセクションと見出しを扱うときに特に便利です。 <section><article><aside><nav> は互いによく入れ子になるので、:is() を使わないと 1 つ 1 つを選択してスタイルを適用するのが難しくなります。

例えば、:is() を使わずに異なる深さの <h1> 要素にスタイルを適用すると、とても複雑になります。

/* 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 */
/* ... 考えたくありません! */

:is() を使用すると、ずっと簡単になります。

/* 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() 疑似クラスは、渡されたセレクターのうちの 1 つにブラウザーが対応していなくても無効になりません。

:is(:valid, :unsupported) {
  ...
}

これは正しく解釈され、ブラウザーが :unsupported に対応していなくても :valid に一致しますが、一方で、

:valid, :unsupported {
  ...
}

これはブラウザーが :unsupported に対応していないと、:valid に対応していても無視されます。

:is() と :where() の違い

この 2 つの疑似クラス関数の違いは、:is() がセレクター全体の詳細度を算出する (その最も詳細な引数の詳細度を取る) のに対し、:where() の詳細度の値は 0 です。具体的な例は :where() リファレンスページ を参照してください。

仕様書

仕様書 策定状況 備考
Selectors Level 4
:is() の定義
草案 初回定義

ブラウザーの実装状況

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
:is()Chrome 完全対応 68
補足 無効
完全対応 68
補足 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
無効 From version 68: this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled). To change preferences in Chrome, visit chrome://flags.
未対応 66 — 71
補足 代替名 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
代替名 非標準の名前 :matches() を使用しています。
無効 From version 66 until version 71 (exclusive): this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled). To change preferences in Chrome, visit chrome://flags.
完全対応 12
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Edge 完全対応 79
補足 無効
完全対応 79
補足 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
無効 From version 79: this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled).
完全対応 79
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Firefox 完全対応 78
完全対応 78
完全対応 77
補足 無効
補足 Enabled by default in Firefox Nightly.
無効 From version 77: this feature is behind the layout.css.is-where-selectors.enabled preference (needs to be set to enabled). To change preferences in Firefox, visit about:config.
完全対応 4
補足 代替名
補足 Doesn't support combinators.
補足 See bug 906353
代替名 非標準の名前 :-moz-any() を使用しています。
IE 未対応 なしOpera 完全対応 55
補足 無効
完全対応 55
補足 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
無効 From version 55: this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled).
未対応 53 — 58
補足 代替名 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
代替名 非標準の名前 :matches() を使用しています。
無効 From version 53 until version 58 (exclusive): this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled).
完全対応 15
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Safari 完全対応 14
完全対応 14
完全対応 9
代替名
代替名 非標準の名前 :matches() を使用しています。
完全対応 5
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
WebView Android 完全対応 ≤37
補足 代替名
完全対応 ≤37
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Chrome Android 未対応 66 — 71
補足 代替名 無効
未対応 66 — 71
補足 代替名 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
代替名 非標準の名前 :matches() を使用しています。
無効 From version 66 until version 71 (exclusive): this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled). To change preferences in Chrome, visit chrome://flags.
完全対応 18
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Firefox Android 完全対応 4
補足 代替名
完全対応 4
補足 代替名
補足 Doesn't support combinators.
補足 See bug 906353
代替名 非標準の名前 :-moz-any() を使用しています。
Opera Android 完全対応 48
補足 無効
完全対応 48
補足 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
無効 From version 48: this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled).
未対応 47 — 50
補足 代替名 無効
補足 Combinators in the selector list argument may not match correctly (see bug 842157).
代替名 非標準の名前 :matches() を使用しています。
無効 From version 47 until version 50 (exclusive): this feature is behind the #enable-experimental-web-platform-features preference (needs to be set to Enabled).
完全対応 14
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Safari iOS 完全対応 14
完全対応 14
完全対応 9
代替名
代替名 非標準の名前 :matches() を使用しています。
完全対応 5
補足 代替名
補足 Doesn't support combinators.
代替名 非標準の名前 :-webkit-any() を使用しています。
Samsung Internet Android 未対応 9.0 — 10.0
代替名
未対応 9.0 — 10.0
代替名
代替名 非標準の名前 :matches() を使用しています。
完全対応 1.0
代替名
代替名 非標準の名前 :-webkit-any() を使用しています。
Support for forgiving selector listChrome 未対応 なしEdge 未対応 なしFirefox 完全対応 82IE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしFirefox Android 完全対応 82Opera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なし

凡例

完全対応  
完全対応
未対応  
未対応
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。
非標準の名前を使用しています。
非標準の名前を使用しています。

関連情報