Main selector guide
Featured and available
Combine conditions with OR, AND, and functional pseudo-classes; compare their matches and inspect how specificity changes.
article, .noticePreparing the scenario and its results…
Selects elements matching either of the two comma-separated branches.
<section class="catalog" aria-label="Catalog for logical and relational selectors">
<article class="card featured">
<span class="badge">New</span>
<h3>Main selector guide</h3>
<p>Featured and available</p>
</article>
<aside class="card archived">
<h3>Archived reference</h3>
<p>Kept for reference</p>
</aside>
<article class="card featured">
<span class="media">Video</span>
<span class="locked">Restricted</span>
<h3>Advanced course</h3>
<p>Restricted content</p>
</article>
<p class="notice">The collection is updated with new examples.</p>
</section>article, .notice {
outline: 3px solid #f97316;
outline-offset: 3px;
background-color: color-mix(in oklch, #f97316 16%, transparent);
}CSS logic and relationships guide
Distinguish OR, AND, and exclusion, compare the special specificity of functional pseudo-classes, and learn to read relative selectors.
The same conditions can change meaning and weight depending on where commas appear and which pseudo-class contains them.
A, BA list matches when at least one branch matches. Each complex selector keeps its own specificity tuple.
A.classSimple selectors written without a combinator must match the same element and add their contributions.
:is() · :where():is() takes the most specific argument; :where() and all of its arguments contribute zero.
E:has(relative)E is the selected element. Relative arguments are evaluated with E as their anchor and may start with a combinator.
Compare the union of independent branches with multiple conditions required on a single element.
A, BSelects an element when it matches at least one branch in the comma-separated list.
Specificity(0, 0, 1) · (0, 1, 0)article, .notice<section>
Matches: <article>Matches</article>
<div>Does not match</div>
Matches: <p class="notice">Matches</p>
</section>button, [role="status"]<div>
Matches: <button>Matches</button>
<a href="#docs">Does not match</a>
Matches: <output role="status">Matches</output>
</div>A.class[attr]Selects one element that simultaneously satisfies every simple selector written without a combinator.
Specificity(0, 2, 1).card.featured<section>
Matches: <article class="card featured">Matches</article>
<article class="card">Does not match</article>
<div class="featured">Does not match</div>
</section>button.primary[aria-pressed="true"]<div>
Matches: <button class="primary" aria-pressed="true">Matches</button>
<button class="primary" aria-pressed="false">Does not match</button>
<a class="primary" aria-pressed="true">Does not match</a>
</div>:is(), :where(), and :not() accept lists, but they do not share the same meaning or specificity.
:is(A, B)Matches when the element satisfies at least one selector in its argument list.
Specificity(0, 1, 0):is(article, aside).featured<section>
Matches: <article class="featured">Matches</article>
Matches: <aside class="featured">Matches</aside>
<section class="featured">Does not match</section>
</section>.toolbar :is(a, button)<nav class="toolbar">
Matches: <a href="#guide">Matches</a>
<span>Does not match</span>
Matches: <button>Matches</button>
</nav>This Baseline status covers :is(), including its forgiving list. The current browser is checked separately in the playground.
:where(A, B)Matches the same elements as :is() for the same argument list.
Specificity(0, 0, 0):where(article, aside).featured<section>
Matches: <article class="featured">Matches</article>
Matches: <aside class="featured">Matches</aside>
<section class="featured">Does not match</section>
</section>.content :where(p, blockquote)<article class="content">
Matches: <p>Matches</p>
Matches: <blockquote>Matches</blockquote>
<aside>Does not match</aside>
</article>This Baseline status covers :where() and its zero-specificity behavior.
:not(A, B)Selects the subject when it matches none of the selectors in the argument.
Specificity(0, 1, 0).card:not(.archived, :has(.locked))<section>
Matches: <article class="card">Matches</article>
<article class="card archived">Does not match</article>
<article class="card"><span class="locked">Restricted</span></article>
</section>section:not(:has(h2, h3))<main>
Matches: <section>
<p>Matches</p>
</section>
<section>
<h2>Does not match</h2>
</section>
</main>This Baseline status represents the Selectors Level 4 form that accepts lists inside :not().
Select a subject by descendants or siblings matching relative selectors anchored to that subject.
:has(relative selector)Selects the subject element when at least one relative selector matches with that element as the anchor.
Specificity(0, 1, 0).card:has(> :is(.badge, .media))<section>
Matches: <article class="card">
<span class="badge">Matches</span>
</article>
<article class="card"><p>Does not match</p></article>
Matches: <aside class="card">
<span class="media">Matches</span>
</aside>
</section>dt:has(+ dt)<dl>
Matches: <dt>Matches</dt>
<dt>Does not match</dt>
<dd>CSS</dd>
<dt>Does not match</dt>
<dd>HTML</dd>
</dl>This Baseline status covers :has(). As a later addition, it is shown separately from core selectors.