A selector on its own says what kind of element to target, but says nothing about its position relative to other elements. Combinators fill that gap: they are the symbols that describe the relationship between two selectors in the HTML.
They turn CSS into a tool capable of reading a page's structure, not just its tags or classes taken in isolation. Without them, a class would need to be placed on every element to target, even when its position alone would be enough to describe it.
Definition
A CSS combinator is the symbol placed between two selectors to describe the relationship that must exist between the matching elements in the HTML: containment, direct parentage, or position among siblings.
The four combinators
CSS defines four combinators, each with a precise use.
/* descendant: a plain space between selectors */
article p {
line-height: 1.6;
}
/* direct child: greater-than sign */
ul > li {
margin-bottom: 8px;
}
/* adjacent sibling: plus sign */
h2 + p {
margin-top: 0;
}
/* general sibling: tilde */
h2 ~ p {
color: #555;
}The descendant combinator, a plain space, targets any element located anywhere inside another one, even several levels deep. The direct child combinator, written >, narrows the target to immediate children only, without reaching further down the tree.
The combinators between siblings
The adjacent sibling combinator, +, targets the element that immediately follows another at the same level, and only the very first one that follows. The general sibling combinator, ~, targets every element that follows, not just the first. In the example above, h2 + p only styles the paragraph sitting right after a heading, while h2 ~ p styles every paragraph that comes after that heading, even past several other elements in between.
| Combinator | Symbol | Relationship targeted |
|---|---|---|
| Descendant | space | Anywhere inside |
| Direct child | > | Immediate child only |
| Adjacent sibling | + | Right after, one element only |
| General sibling | ~ | After, every matching element |
A common trap: descendant versus direct child
Confusing nav a with nav > a is a classic mistake. The first targets any link inside a navigation, even one buried in a dropdown submenu. The second only targets links that are direct children of the navigation, leaving submenu links untouched, which radically changes the result on a complex navigation.
Combinators and specificity
Unlike a CSS selector such as a class or an id, a combinator adds nothing to the specificity calculation. Only the selectors it links count toward that score. nav > a and nav a therefore carry the exact same specificity weight, even though their behavior differs radically depending on how deep the targeted HTML goes. This distinction becomes useful when pairing a combinator with an Attribute selector, for example to precisely target active links inside a navigation without ever inflating the rule.
Frequently asked questions
Yes, a selector like section > h2 + p combines a direct child and an adjacent sibling to describe a precise chain of relationships across several elements.
No, sibling combinators only target elements that follow in the HTML, never ones that come before. CSS does not allow targeting an element based on what comes after it that way.
.button.active?A compound selector with no space targets a single element that meets several conditions at once, while a combinator links two different elements in the HTML based on their position relative to each other.