Working with CSS3's General sibling combinator.

Michael Weaver
Oct 21, 2014 · 2 min read

Until this week I had never heard of the General sibling combinator.

I came across it after doing some front-end development work.
I wanted to target the first section element with the class target.
For instance…

HTML
<section></section>
<section class="target"></section>
<section class="target"></section>
<section class="target"></section>
<section></section>

I imagine like yourselves, I thought I would use a pseudo class. So I tried…

CSS
section.target:first-of-type {}
section.target:nth-of-type(1) {}
section.target:first-child {}

For some reason these methods have always worked for me in the past, but this time no styling was being applied.

So after doing some investigation, I came across a Stack Overflow post with another developer asking a similar question.

One answer really intrigued me. A user who goes by the username BoltClock proposed a solution using CSS3's General sibling combinator, something I had never heard of.

One misconception I had fell for is that I could target the first element with a class by using one of the above options.

Using the General sibling combinator

The general sibling combinator is made of the “tilde” (U+007E, ~) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.

I’ll be honest, the above quote from the W3C page made little sense to me, but BoltClock’s explanation made more.

By using the General sibling combinator, we can target all section elements with the class of target, including the first, and then we can target all elements with the class of target except the first, in a way cancelling out the styling for the rest of the elements.

So using the example shown earlier you could style the first section with the class target by doing the following…

HTML
<section></section>
<section class="target"></section>
<section class="target"></section>
<section class="target"></section>
<section></section>
CSS
body > section.target { border: 1px solid red; }
body > section.target ~ section.target { border: none; }

This worked perfectly for me.

Image for post
Image for post

Have you tried using the General sibling combinator?

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store