:is() CSS pseudo-class

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2021.

The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list. This is useful for writing large selectors in a more compact form.

Note: Originally named :matches() (and :any()), this selector was renamed to :is() in CSSWG issue #3258.

Try it

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>

Syntax

css
:is(<forgiving-selector-list>) {
  /* ... */
}

Parameters

The :is() pseudo-class requires a selector list, a comma-separated list of one or more selectors as its argument. The list must not contain a pseudo-element, but any other simple, compound, and complex selectors are allowed.

Difference between :is() and :where()

The difference between the two is that :is() counts towards the specificity of the overall selector (it takes the specificity of its most specific argument), whereas :where() has a specificity value of 0. This is demonstrated by the example on the :where() reference page.

Forgiving Selector Parsing

The specification defines :is() and :where() as accepting a forgiving selector list.

In CSS when using a selector list, if any of the selectors are invalid then the whole list is deemed invalid. When using :is() or :where() instead of the whole list of selectors being deemed invalid if one fails to parse, the incorrect or unsupported selector will be ignored and the others used.

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

Will still parse correctly and match :valid even in browsers which don't support :unsupported, whereas:

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

Will be ignored in browsers which don't support :unsupported even if they support :valid.

Examples

Simplifying list selectors

The :is() pseudo-class can greatly simplify your CSS selectors. For example, take the following 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;
}

You can replace it with:

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;
}

Simplifying section selectors

The :is() pseudo-class is particularly useful when dealing with HTML sections and headings. Since <section>, <article>, <aside>, and <nav> are commonly nested together, without :is(), styling them to match one another can be tricky.

For example, without :is(), styling all the h1 elements at different depths could be very complicated:

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! */

Using :is(), though, it's much easier:

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() does not select pseudo-elements

The :is() pseudo-class does not match pseudo-elements. So rather than this:

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

or this:

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

instead do:

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

Specifications

Specification
Selectors Level 4
# matches-pseudo

Browser compatibility

desktop mobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
:is()
Chrome – Full support
Chrome 12 (Release date: 2011-06-07)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Chrome – Full support
Chrome 88 (Release date: 2021-01-19)
footnote Full support
Edge – Full support
Edge 79 (Release date: 2020-01-15)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Edge – Full support
Edge 88 (Release date: 2021-01-21)
footnote Full support
Firefox – Full support
Firefox 4 (Release date: 2011-03-22)
footnote , altname
altname Alternate name: :-moz-any()
footnote Doesn't support combinators.
footnote See bug 906353.
Firefox – Full support
Firefox 78 (Release date: 2020-06-30)
footnote Full support
Opera – Full support
Opera 15 (Release date: 2013-07-02)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Opera – Full support
Opera 74 (Release date: 2021-02-02)
footnote Full support
Safari – Full support
Safari 5 (Release date: 2010-06-07)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Safari – Full support
Safari 9 (Release date: 2015-09-30)
altname
altname Alternate name: :matches()
Safari – Full support
Safari 14 (Release date: 2020-09-16)
footnote Full support
Chrome Android – Full support
Chrome Android 18 (Release date: 2012-06-27)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Chrome Android – Full support
Chrome Android 88 (Release date: 2021-01-19)
footnote Full support
Firefox for Android – Full support
Firefox for Android 4 (Release date: 2011-03-29)
footnote , altname
altname Alternate name: :-moz-any()
footnote Doesn't support combinators.
footnote See bug 906353.
Firefox for Android – Full support
Firefox for Android 79 (Release date: 2020-07-28)
footnote Full support
Opera Android – Full support
Opera Android 14 (Release date: 2013-05-21)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Opera Android – Full support
Opera Android 63 (Release date: 2021-04-16)
footnote Full support
Safari on iOS – Full support
Safari on iOS 5 (Release date: 2011-10-12)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
Safari on iOS – Full support
Safari on iOS 9 (Release date: 2015-09-16)
altname
altname Alternate name: :matches()
Safari on iOS – Full support
Safari on iOS 14 (Release date: 2020-09-16)
footnote Full support
Samsung Internet – No support
Samsung Internet 9 – 9.4 (Release date: 2018-09-15)
altname
footnote Removed in 10 and later
altname Alternate name: :matches()
Samsung Internet – Full support
Samsung Internet 1 (Release date: 2013-04-27)
altname
altname Alternate name: :-webkit-any()
Samsung Internet – Full support
Samsung Internet 15 (Release date: 2021-08-13)
footnote Full support
WebView Android – Full support
WebView Android 4.4 (Release date: 2013-12-09)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
WebView Android – Full support
WebView Android 88 (Release date: 2021-01-19)
footnote Full support
WebView on iOS – Full support
WebView on iOS 5 (Release date: 2011-10-12)
footnote , altname
altname Alternate name: :-webkit-any()
footnote Doesn't support combinators.
WebView on iOS – Full support
WebView on iOS 9 (Release date: 2015-09-16)
altname
altname Alternate name: :matches()
WebView on iOS – Full support
WebView on iOS 14 (Release date: 2020-09-16)
footnote Full support
Support for forgiving selector list
Chrome – Full support
Chrome 88 (Release date: 2021-01-19)
footnote Full support
Edge – Full support
Edge 88 (Release date: 2021-01-21)
footnote Full support
Firefox – Full support
Firefox 82 (Release date: 2020-10-20)
footnote Full support
Opera – Full support
Opera 74 (Release date: 2021-02-02)
footnote Full support
Safari – Full support
Safari 14 (Release date: 2020-09-16)
footnote Full support
Chrome Android – Full support
Chrome Android 88 (Release date: 2021-01-19)
footnote Full support
Firefox for Android – Full support
Firefox for Android 82 (Release date: 2020-10-20)
footnote Full support
Opera Android – Full support
Opera Android 63 (Release date: 2021-04-16)
footnote Full support
Safari on iOS – Full support
Safari on iOS 14 (Release date: 2020-09-16)
footnote Full support
Samsung Internet – Full support
Samsung Internet 15 (Release date: 2021-08-13)
footnote Full support
WebView Android – Full support
WebView Android 88 (Release date: 2021-01-19)
footnote Full support
WebView on iOS – Full support
WebView on iOS 14 (Release date: 2020-09-16)
footnote Full support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Uses a non-standard name
Has more compatibility info.

See also