CSS Selectors, Combinators, Pseudo-Classes & Specificity Reference
Master modern CSS selectors including :has(), :is(), :where(), :nth-child(An+B), attribute matching, and cascade scoring.
Table of Contents
Combinators & Hierarchical Selectors
Relationships between parent, child, and sibling elements.
| Pattern | Selector Type | Explanation & Target |
|---|---|---|
| `div p` | Descendant selector | Matches any `<p>` element nested inside a `<div>`, regardless of depth. |
| `ul > li` | Direct child selector | Matches only `<li>` elements that are direct children of `<ul>`. |
| `h2 + p` | Adjacent sibling selector | Matches `<p>` immediately preceded by an `<h2>` element. |
| `h2 ~ p` | General sibling selector | Matches any `<p>` that shares the same parent and appears after `<h2>`. |
Modern Pseudo-Classes (:has, :is, :where)
Next-generation relational and grouping selectors widely supported in all evergreen browsers.
| Selector | Specificity Impact | Use Case & Example |
|---|---|---|
| `article:has(img)` | Inherits inner selector | Parent selector! Styles `<article>` only if it contains an `<img>` tag. |
| `:is(h1, h2, h3)` | Takes specificity of most specific argument | Reduces repetition when styling multiple elements with common children. |
| `:where(h1, h2, h3)` | ALWAYS ZERO specificity (0,0,0) | Perfect for CSS resets and base styles that need easy overriding. |
Specificity Calculation Formula
How browsers resolve competing stylesheet declarations.
| Category | Weight Score | Examples |
|---|---|---|
| Inline styles | 1,0,0,0 | `style="color: red;"` |
| ID selectors | 0,1,0,0 | `#header`, `#sidebar` |
| Classes, attributes, pseudo-classes | 0,0,1,0 | `.btn`, `[type="text"]`, `:hover`, `:first-child` |
| Elements, pseudo-elements | 0,0,0,1 | `div`, `p`, `::before`, `::after` |
Interactive Client-Side Tools for this Guide
Test and run these patterns directly inside your browser with zero server uploads:
Frequently Asked Questions
What is the "parent selector" in CSS?
The `:has()` pseudo-class acts as the long-awaited CSS parent selector. For example, `figure:has(figcaption)` allows you to apply styling to `<figure>` only when a caption is present.
What is the difference between :is() and :where()?
Both take a list of selectors to match, but `:where()` always assigns 0 specificity to the selector list, making it trivially easy to override without `!important`.