What is a Combinator?
A combinator is a symbol placed between two selectors that describes the relationship between the elements they match — descendant, direct child, or sibling.
Combinator Types
| Combinator | Syntax | Matches |
|---|---|---|
| Descendant | A B | Any B inside A, at any depth |
| Child | A > B | Any B that is a direct child of A |
| Adjacent sibling | A + B | The B that comes immediately after A |
| General sibling | A ~ B | Any B that comes after A, sharing the same parent |
Descendant vs Child Combinator
<style>
.card p {
color: steelblue; /* every <p>, no matter how deeply nested */
}
.card > p {
font-weight: bold; /* only direct <p> children of .card */
}
</style>
<div class="card">
<p>Direct child — bold and blue.</p>
<div>
<p>Nested deeper — blue, but not bold.</p>
</div>
</div>Output
Adjacent and General Sibling Combinators
<style>
h2 + p {
font-weight: bold; /* only the paragraph immediately after an h2 */
}
h2 ~ p {
color: gray; /* every paragraph after an h2, sharing the same parent */
}
</style>
<h2>Title</h2>
<p>Right after the heading — bold and gray.</p>
<p>Also after the heading — gray, but not bold.</p>Output
Combining with Other Selectors
Combinators can be chained with classes, IDs, and pseudo-classes to build precise selectors, like .nav > li:hover to target only the direct <li> children of a nav on hover.
A Precise Combined Selector
<style>
.nav > li:hover {
background: #eef4fb;
}
</style>
<ul class="nav" style="list-style: none; padding: 0;">
<li style="padding: 8px;">Home</li>
<li style="padding: 8px;">About</li>
</ul>Output
Descendant is the Most Common (and Loosest)
The descendant combinator (a plain space) is the most frequently used but also the loosest — it matches at any depth, which can unintentionally style elements you didn’t mean to target as your markup grows.
Best Practice
Prefer the child combinator (>) over the descendant combinator when you specifically mean "direct children only" — it keeps styles from leaking into deeply nested, unrelated elements.