Grokking CSS Combinators A.K.A. Fancy Pants Selectors

It looks harder than it really is

If you've never bothered to learn about CSS combinators they can look like an alien language. But once you spend ten minutes with the basics you should be able to figure out what's happening really quickly. I used to avoid using these selectors because my old foes IE6 and IE7 didn't support them, but we don't need to worry about those guys anymore (right?!?). Instead we should use whatever selectors make sense and then figure out a way to make our design work in browsers we need to support.

.childselectors > ul > li {...}

First up is the child selector. The normal selectors you are probably familiar with are called descendant selectors. They look like this:

  ul li { margin-top: 5px; }
  

With this descendant selector you are selecting every <li> that is under the <ul>. But what if one of the <li> tags of the <ul> has an inner list with other <li> tags? And you don't want to style those? That's where the child selector comes in. It only selects the children of the element that match the rule, not all of the descendants. It's easier to understand with an example.

<ul>
    <li>
      <ul>
        <li>inner list</li>
        <li>inner list</li>
      </ul>
    </li>
    <li>outer list</li>
    <li>outer list</li>
  </ul>
.childselectors > ul > li{
    border: 5px solid red;
}

.childselectors > ul > li > ul{
    border: 5px solid blue;
}
    • inner list
    • inner list
  • outer list
  • outer list

I love how precise you can be with these selectors without having to create special classes.

.adjacentsibling h3 + p{ color: red; }

Descendant and child selectors handle elements below other elements. What if you want to grab an element next to another element? For example, each section of this blog starts with an <h2> tag which is followed by content wrapped in <p> tags. The <p> tags are next to the <h2> tags and we can select them using an adjacent selector, which is the plus sign.

For this example I want to make the text of the first paragraph of each section red, which is basically like saying the first <p> tag following the first <h2> tag of each section. We can do this using an adjacent selector, like so:

<h3>example header</h3>
<p>This is the first paragraph and I should be red.</p>
<p>This is the second paragraph and I should be normal.</p>
    .adjacentsibling h3 + p{
       color: red;
    }

example header

This is the first paragraph.

This is the second paragraph.

.generalsibling h3 ~ p

The adjacent sibling selector only gives us the first sibling that matches the rule, but what if you want all the siblings? Just change the + to a ~ and you're good to go.

<h3>example header</h3>
<p>This is the first paragraph and I should be red.</p>
<p>This is the second paragraph and I should be normal.</p>
    .adjacentsibling h3 ~ p{
       color: red;
    }

example header

This is the first paragraph. I should be red.

This is the second paragraph. I should also be red.

The tiny screwdriver in the Swiss Army Knife

These selectors are not the coolest CSS feature of all time. They are more like that tiny screwdriver that comes with some Swiss Army knives. I almost never need it but on occasion it's the only thing that will work.

(P.S. Swiss Army Knives are awesome).

Sketching with CSS will teach you how to design in the browser.

Sketching with CSS

Blow away your clients with your fast turnaround time. Bend CSS layouts to your will. Show your clients comps they can actually click on.

Get a free chapter and an 8 day email course on rapid prototyping in the browser.

Share this article with your friends:

Hey there, I'm Sean.

I'm probably a lot like you. I make stuff for the web. I have a CS degree, but the last 8 years of my career have been a more potent teacher.

Sean Fioritto

Recently, I wrote a book on web development called Sketching with CSS. I also run a training company for developers. I'm an author in Smashing Magazine and I've written some cool open source projects.

Today, I'm an entrepreneur. In the not so distant past I did the usual 9-5 thing doing web development for a couple of big companies.

I'd love to meet you on Twitter.

You can also email me: [email protected]