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
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.
