CSS :is() Pseudo-Class

The CSS :is() pseudo-class matches an element against a list of selectors. It simplifies complex selectors, reduces repeated code, and makes CSS stylesheets easier to read and maintain.

:is() Syntax

:is(selector1, selector2, selector3) {
  property: value;
}

The :is() pseudo-class accepts a comma-separated list of selectors. An element matches when it satisfies at least one selector in the list.

Basic Example

:is(h1, h2, h3) {
  color: #006699;
}

This rule applies the same text color to <h1>, <h2>, and <h3> elements.

Class Selector Example

:is(.primary, .secondary) {
  padding: 10px;
}

This rule applies padding to elements with either the primary or secondary class.

Combined Selector Example

article :is(h2, h3) {
  margin-bottom: 15px;
}

This rule targets second-level and third-level headings that are descendants of an <article> element.

How :is() Works

The :is() pseudo-class allows multiple selector alternatives to be written within a single selector expression.

Without :is()

article h2,
article h3,
article h4 {
  color: #006699;
}

With :is()

article :is(h2, h3, h4) {
  color: #006699;
}

Both examples select the same elements. The second version avoids repeating the article selector.

Matching Any Selector

An element only needs to match one selector inside :is(). It does not need to match every selector in the list.

Combining with Other Selectors

.content :is(p, li) {
  line-height: 1.6;
}

This rule selects paragraphs and list items inside elements with the content class.

No JavaScript Required

The browser evaluates the selectors automatically. JavaScript is not required to use :is().

Grouping Selectors

The :is() pseudo-class is especially useful when several selectors share a common parent or ancestor.

Navigation Links

nav :is(a, button) {
  font-weight: bold;
  color: #006699;
}

This rule styles links and buttons inside a navigation element.

Form Controls

form :is(input, select, textarea) {
  padding: 8px;
  border: 1px solid #ccc;
}

This rule applies consistent styling to three types of form controls.

Multiple Containers

:is(header, footer) a {
  text-decoration: none;
}

This rule removes underlines from links inside either a header or footer.

Grouping vs. Repetition

Use :is() when grouping alternatives makes a selector easier to understand. A simple comma-separated selector list may be clearer when no repeated structure exists.

Complex Selectors

The :is() pseudo-class can contain compound and complex selectors, including selectors that use combinators.

Descendant Selectors

:is(article p, aside p) {
  line-height: 1.6;
}

This rule selects paragraphs inside an article or aside.

Child Combinators

:is(article > h2, section > h2) {
  color: #006699;
}

This rule selects second-level headings that are direct children of an article or section.

Pseudo-Classes Inside :is()

a:is(:hover, :focus-visible) {
  text-decoration: underline;
}

This rule underlines links when they are hovered or match :focus-visible.

Nested Functional Pseudo-Classes

article :is(h2, h3):not(.excluded) {
  color: #006699;
}

This rule selects second-level and third-level headings inside an article unless they have the excluded class.

Relative Selectors

The selector list inside :is() does not accept a leading combinator by itself. For relationships based on relative selectors, use a suitable pseudo-class such as :has().

Forgiving Selector Lists

The :is() pseudo-class uses a forgiving selector list. Invalid or unsupported selectors inside the list can be discarded without invalidating the remaining valid alternatives.

Example

:is(h2, :unsupported-example, h3) {
  color: #006699;
}

If the browser does not recognize :unsupported-example, it can still apply the rule to <h2> and <h3> elements.

Traditional Selector Lists

h2,
:unsupported-example,
h3 {
  color: #006699;
}

In a traditional selector list, an invalid selector generally invalidates the entire style rule.

All Selectors Invalid

If every alternative inside :is() is invalid or unsupported, the pseudo-class matches no elements.

Important Limitation

The forgiving behavior applies to the selector list inside :is(). It does not make invalid CSS declarations or unrelated syntax errors valid.

:is() Specificity

The :is() pseudo-class does not add its own specificity. Instead, its specificity is determined by the most specific selector in its argument list.

Specificity Examples

Selector Specificity
:is(h1, h2) 0-0-1
:is(.title, h2) 0-1-0
:is(#main, .content) 1-0-0
article :is(h2, h3) 0-0-2
.content :is(h2, .title) 0-2-0
button:is(:hover, :focus-visible) 0-1-1

Highest Specificity Wins

:is(h2, #special) {
  color: #006699;
}

The selector has a specificity of 1-0-0 because #special has the highest specificity in the list. This specificity applies even when the matched element is an <h2> without that ID.

Specificity Is Not Based on the Matching Alternative

The browser does not calculate a different specificity for each matched alternative. It uses the highest specificity in the entire valid selector list.

Avoid Unnecessary IDs

Including an ID selector inside :is() can unexpectedly increase the specificity of the entire selector.

:is() vs. :where()

The :is() and :where() pseudo-classes both accept selector lists, but they handle specificity differently.

Comparison

Feature :is() :where()
Matches selector alternatives Yes Yes
Forgiving selector list Yes Yes
Specificity Highest argument specificity Always 0-0-0
Typical use Grouping selectors while retaining specificity Creating easily overridden styles

Using :is()

:is(h2, h3) {
  color: #006699;
}

This selector has a specificity of 0-0-1.

Using :where()

:where(h2, h3) {
  color: #006699;
}

This selector has a specificity of 0-0-0.

Choosing Between Them

Use :is() when the specificity of the selectors should be preserved. Use :where() when creating low-specificity styles that should be easy to override.

:is() vs. :not()

The :is() and :not() pseudo-classes both accept selector lists, but they perform opposite matching operations.

Comparison

Selector Matching Condition
:is() Matches an element satisfying at least one selector in the list.
:not() Matches an element satisfying none of the selectors in the list.

Using :is()

:is(h2, h3) {
  color: #006699;
}

This rule styles second-level and third-level headings.

Using :not()

h2:not(.excluded) {
  color: #006699;
}

This rule styles second-level headings that do not have the excluded class.

Combining Both

:is(h2, h3):not(.excluded) {
  color: #006699;
}

This rule styles second-level and third-level headings except those with the excluded class.

Practical Uses

The :is() pseudo-class is useful for simplifying repeated selector patterns.

Heading Styles

article :is(h2, h3, h4) {
  color: #006699;
}

Apply consistent styling to multiple heading levels inside an article.

Navigation Elements

nav :is(a, button) {
  font-size: 1rem;
}

Style navigation links and buttons using one rule.

Form Controls

form :is(input, select, textarea) {
  border-radius: 4px;
}

Apply shared styles to several types of form controls.

Interactive States

a:is(:hover, :focus-visible) {
  color: #006699;
}

Apply the same color when a link is hovered or has visible keyboard focus.

Reducing Repetition

Use :is() when a selector contains a repeated parent, ancestor, or common structure.

Limitations

Although :is() simplifies selectors, it has several important considerations.

Specificity Can Increase

The most specific argument determines the specificity of the entire :is() expression, even when another alternative matches.

No Leading Combinators

The selector list does not accept a relative selector beginning with a combinator such as > or +.

Invalid Alternatives Are Ignored

Unsupported or invalid selectors inside the forgiving selector list are discarded. If none remain valid, the pseudo-class matches nothing.

Not Always Shorter

For simple selectors, a traditional comma-separated list may be easier to read.

Not a Replacement for Every Selector

The :is() pseudo-class groups alternatives. It does not replace relational selectors such as :has() or exclusion selectors such as :not().

Best Practices

  • Use :is() to reduce repeated selector patterns.
  • Group related selectors that share the same CSS declarations.
  • Keep selector lists short enough to remain readable.
  • Remember that the most specific argument determines specificity.
  • Avoid unnecessary ID selectors inside :is().
  • Use :where() when zero specificity is preferred.
  • Use :not() when elements should be excluded.
  • Test complex selectors to ensure they match the intended elements.

:is() Example

This example uses :is() to style several heading levels with one CSS rule. The first three headings share the same blue text color, while the paragraph retains its default color.

HTML

<div class="is-demo">
  <h2>Second-Level Heading</h2>
  <h3>Third-Level Heading</h3>
  <h4>Fourth-Level Heading</h4>
  <p>This paragraph is not selected by :is().</p>
</div>

CSS

.is-demo :is(h2, h3, h4) {
  color: #006699;
  margin-bottom: 10px;
}
.is-demo h2 {
  font-size: 1.375rem;
}
.is-demo h3 {
  font-size: 1.25rem;
}
.is-demo h4 {
  font-size: 1.125rem;
}
.is-demo p {
  color: #333;
}

Browser Result

Play in Editor

Note: The :is() selector matches the three heading elements. The paragraph does not match because p is not included in the selector list.

Browser Support

Baseline: Widely available. The :is() pseudo-class is supported in modern versions of Chrome, Edge, Firefox, Safari, and other major browsers.

For current compatibility information, visit Can I Use? .

Specifications

The :is() pseudo-class is defined in CSS Selectors Level 4 as the matches-any pseudo-class. It accepts a forgiving selector list and uses the specificity of its most specific argument.

Selectors Level 4 - :is()