:is()
Matches an element against any selector in a list. Shortens long, repetitive selectors into a single notation.
Example
#.link:is(:hover, :focus-visible) {
color: #fff;
text-decoration-color: #a78bfa;
text-decoration-thickness: 2px;
}<style>.link { color: #c4b5fd; text-underline-offset: 4px; text-decoration-color: #52525b; }</style>
<p style="margin: 0;">Hover over the <a class="link" href="#">first link</a>, or click into the preview and tab to the <a class="link" href="#">second one</a>.</p>Definition and usage
#The :is() pseudo-class takes a list of selectors and matches when the element matches any one of them. Its main advantage is a shorter notation: instead of article h2, article h3, section h2, section h3, :is(article, section) :is(h2, h3) is enough.
The list inside :is() is forgiving. If one of the selectors is invalid or unsupported, the browser simply skips it, and the rest still works. A plain comma-separated list would reject the whole rule in that situation.
The specificity of :is() is the weight of the strongest selector in the list, regardless of which element it actually matches through. :is(#hero, p) has a weight of (1, 0, 0) even for plain paragraphs. If you want the same notation with zero weight, use :where().
Pseudo-elements canโt appear inside the parentheses: :is(::before, ::after) wonโt work, so pseudo-elements have to be listed separately.
Syntax
#:is( <selector list> )Example selectors
#- Headings inside
articleorsection. One selector instead of two. - The list can also sit at the end: a heading and a paragraph inside
aside. :is(article, aside) :is(h4, p)
Two lists give four combinations in one short notation.:is(section, :unknown-selector) p
The unknown selector:unknown-selectorgets skipped, and the rest of the list still works. A plain comma-separated list would reject the whole rule.
Example selectors in practice
#:is(article, section) h4
article or section. One selector instead of two.:is(article, section) h4 { background: #7c3aed; color: #fff; }aside :is(h4, p)
aside.aside :is(h4, p) { background: #7c3aed; color: #fff; }:is(article, aside) :is(h4, p)
:is(article, aside) :is(h4, p) { background: #7c3aed; color: #fff; }:is(section, :unknown-selector) p
:unknown-selector gets skipped, and the rest of the list still works. A plain comma-separated list would reject the whole rule.:is(section, :unknown-selector) p { background: #7c3aed; color: #fff; }More examples
#:is(ul, ol) :is(ul, ol) {
margin: 4px 0;
color: #a1a1aa;
font-size: 14px;
}<ul class="stage" style="margin: 0; padding: 10px 10px 10px 30px;">
<li>Courses
<ol><li>HTML and CSS</li><li>JavaScript</li></ol>
</li>
<li>Docs
<ul><li>Selectors</li></ul>
</li>
</ul>One rule covers four cases: ul ul, ul ol, ol ul, and ol ol.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Use
:is()to group states:.btn:is(:hover, :focus-visible). You get the mouse and keyboard-focus effect in one rule. - Watch the weight. A single ID in the list raises the specificity of the whole pseudo-class, even for elements that match through a class.
- When writing base styles meant to be easy to override, swap
:is()for:where().
Related entries
#- :where()Works like :is(), but always has zero specificity. Ideal for base styles that should be easy to override.
- :not()Selects elements that match neither the given selector nor any selector in the list.
- :has()Selects an element based on what it contains or what follows it. Lets you style a parent according to its children.
- A, BA comma combines several selectors into a single rule, to give them the same styles without repeating declarations.
- SpecificityA selectorโs weight, which decides which rule wins when several rules set the same property on the same element.
Spotted a mistake or missing an example? Write to us.