Combinators are used to extend and enhance simple CSS selectors, making them far more powerful. I’ve introduced several combinators in previous articles:
Symbol | Creates | Example |
---|---|---|
(space) | Descendant selector | blockquote p
|
> | Child selector | a > img
|
+ | Adjacent sibling selector | h1 + p
|
* | Universal selector | div *
|
One combinator that I haven’t talked about extensively is ~ (tilde), which creates a general sibling selector.
An Example
Given the following markup, using content from Marcus Aurelis’ Meditations:
<p>For such a purpose frees a man from trouble, and warfare, and all artifice and ostentatious display.
<h2>Book Five</h2>
<p>In the morning when you rise unwillingly, let this thought be present: I am rising to the work of a human being.
<div>
<p>Why then am I dissatisfied if I am going to do the things for which I exist and for which I was brought into the world?
</div>
<p>Or have I been made for this, to lie in the bed-clothes and keep myself warm?
We could apply this CSS:
h2 ~ p {
font-style: italic;
}
Which produces:
For such a purpose frees a man from trouble, and warfare, and all artifice and ostentatious display.
Book Five
In the morning when you rise unwillingly, let this thought be present: I am rising to the work of a human being.
Why then am I dissatisfied if I am going to do the things for which I exist and for which I was brought into the world?
Or have I been made for this, to lie in the bed-clothes and keep myself warm?
The general sibling selector affects elements after the leading element, but which are at the same level: note that the paragraph inside the <div>
remains unaffected, but the paragraph after it is italicized.
This feature allows sibling selectors to be used in interesting ways, “leaping” over elements to affect others.
For example, let’s take the following:
<a href="#">Three little maids</a>
<hr />
<div>
<p>From school are we…
</div>
Say we want a hover on the link to affect the content of the div
. We can’t use an adjacent selector, as the link isn’t directly next to the div
. We could “chain” a series of adjacent selectors to account for the horizontal rule, but that would be horribly long, ugly, and inefficient. Instead, we’ll use a sibling selector:
a:hover ~ div {
color: red;
}
That works perfectly, as you can see by hovering over the link below:

A good example of more complex child selectors with other combinators can be found in my CSS-driven Visual Database.
The important thing to remember about sibling selectors is that they must start at the same level as the elements they are affecting: if the link above was buried inside another element, we couldn’t “work our way out” of it to affect other elements.
Photograph by AP Photographie, licensed under Creative Commons
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/XNVevG