The power of sibling combinators

CSS has a built-in tool called sibling combinators that can relate several selectors to each other and use this relationship for styling.

For example, if you want to style paragraphs, then you use something like the following:

p {
  margin: 1.5rem 0;
}

Pretty straightforward!

However, if you want to add a particular style only when that paragraph follows a specific HTML tag, using sibling combinators is an excellent approach.

Permalink to heading 4 types 4 types

There are four types of combinators:

TypeSymbol
descendenta space
child>
adjacent+
general sibling~

Source: MDN - CSS combinators

Permalink to heading Descendent combinator Descendent combinator

.nav-menu a {
  color: lightblue;
}

The above example is the most widely used combinator. It selects all descendents of an element. It’s pretty cool to group styles, preventing harmful side effects elsewhere on the page.

Permalink to heading The child combinator The child combinator

ul.my-list > li {
  margin-left: 1.5rem;
}

Unlike the descendent combinator, this one selects direct children only. It’s pretty cool to style nested lists, for example.

Permalink to heading The adjacent combinator The adjacent combinator

h2 + p:first-letter {
  font-size: 175%;
}

This one selects the direct sibling of the first element. Only paragraphs that immediately follow an h2 will be selected in the example above.

Permalink to heading The general sibling combinator The general sibling combinator

h2 ~ p {
  padding: .5rem;
  background-color: black;
  color: white;
}

The general sibling combinator selects all siblings of the first element. In the example above, all paragraphs that come after an h2 will be selected.

You can use the general sibling combinator to toggle a div with CSS only. Not that it’s complicated to code in JavaScript, but CSS can do that:

<label for="mycheckbox">Check me</label>
<input type="checkbox" id="mycheckbox" class="mycheckbox">

<p class="mydiv">
Show me
</p>
.mydiv {
  display: none;
  background: yellow;
  padding: 7px;
}
.mycheckbox:checked ~ .mydiv {
   display: block;
}

Permalink to heading Stay focus Stay focus

These combinators are powerful but quite misknown. As far as I know, the primary purpose is to style specific HTML parts accurately.

They are a great alternative to some approaches that involve meaningless HTML classes and over-complicated HTML skeletons with tones of div.

If your CSS combinator does not work for some reason, you likely misuse it.

You can bookmark this post and/or the documentation to ease your debug.


I do my best to update all my contents, but keep it mind that "The power of sibling combinators" has been published many months ago.