CSS sibling selectors

I recently discovered CSS sibling selectors, and an awesome way to take advantage of them. Needless to say, mind was blown so I had to blog about it!

First of all, about sibling selectors themselves: they match an element that’s on the same level as another element, either directly after it (adjacent sibling selector) or anywhere in the same level (general sibling selector).

For example, given the following CSS code:

h1 + p { color: red; }

And the following HTML:

<div>
  <h1>Hello!</h1>
  <p>This is red</p>
  <p>This isn't</p>
</div>

The first paragraph will be red because it’s right after an h1.

Likewise, if we use the general sibling selector:

h1 ~ p { color: red; }
<div>
  <h1>Hello!</h1>
  <div>We can even have another element in between.</div>
  <p>This is red.</p>
  <span>It doesn't matter if they're right next to each other as long as they're on the same level</span>
  <p>This is also red!</p>
  <div><p>However, this isn't red</p></div>
</div>
<p>this isn't red</p>

As you can see, any <p> tag that follows an <h1> tag in the same level of the DOM will match the CSS rule.

So, what’s so cool about this? How can you take advantage of it? Imagine the following scenario:

<div>
    <h1>Supernatural Directory</h1>
    <p>Match only:</p>

    <input type="radio" name="supernatural" id="all" checked/> <label for="all">All</label>
    <input type="radio" name="supernatural" id="werewolves" /> <label for="werewolves">Werewolves</label>
    <input type="radio" name="supernatural" id="fairies" /> <label for="fairies">Fairies</label>
    <input type="radio" name="supernatural" id="vampires" /> <label for="vampires">Vampires</label>

    <h1 class="directory werewolves all">Werewolves</h1>
    <ul class="directory werewolves all">
        <li>Rodney Robinson</li>
        <li>Matthew Phillips</li>
        <li>Rebecca Vasquez</li>
    </ul>
    <h1 class="directory fairies all">Fairies</h1>
    <ul class="directory fairies all">
        <li>Deborah Wong</li>
        <li>Sara Douglas</li>
        <li>Jean Gutierrez</li>
    </ul>

    <h1 class="directory vampires all">Vampires</h1>
    <ul class="directory vampires all">
        <li>Jesse Peters</li>
        <li>Michael Hunter</li>
        <li>Willie Washington</li>
    </ul>
</div>

We obviously want to show only one of the categories by pressing one of the radio buttons. Obviously, this is easy enough to do with javascript, but did you know you can do it with just CSS? By taking advantage of sibling selectors, you can!

First, let’s hide all the .directory elements:

.directory {
    display: none;
}

Now, if we do this:

#all:checked ~ .all {
    display: block;
}

This means that all elements with the ‘all’ class after the checked ‘all’ radio button will be visible! If you use this code, your whole directory will be visible again since ‘all’ is checked by default, and when you select another category nothing should be visible.

You probably know what to do from here, but if you just change that CSS to:

#all:checked ~ .all, #werewolves:checked ~ .werewolves, #fairies:checked ~ .fairies, #vampires:checked ~ .vampires {
    display: block;
}

Now, by toggling one of the checkboxes, the right category will toggle! This is perfect for making some effects without javascript.

In closing I’d like to give credit to the book that taught me this trick, “Responsive Web Design by Example” by Thoriq Firdaus. I think it’s a decent book for people like me that are technical but not that good at design, it teaches you to make some sexy-looking websites, and I hope that it’ll help me improve my design skills!

Until next time,

One thought on “CSS sibling selectors

Leave a Comment

Your email address will not be published. Required fields are marked *