Complete CSS Course Module 2: Beginner: CSS Selectors

CSS Combinators: Descendant, Child and Sibling Selectors

  • Beginner
  • Lesson 2.2
  • 4 min read
  • 5 of 77 in the course

In short

CSS combinators select elements based on their position in the HTML. Learn the descendant, child, adjacent sibling and general sibling selectors with clear examples. What is a CSS combinator? HTML is like a family tree. An element inside another element is its child.

CSS combinators select elements based on their position in the HTML. Learn the descendant, child, adjacent sibling and general sibling selectors with clear examples.

What is a CSS combinator?

HTML is like a family tree. An element inside another element is its child. Elements next to each other with the same parent are siblings. Any element nested inside another, at any depth, is a descendant.

A combinator is a symbol between two selectors that describes their family relationship. There are four:

CombinatorSymbolSelects
DescendantspaceElements inside another, at any depth
Child>Direct children only
Adjacent sibling+The very next sibling
General sibling~All following siblings

The descendant selector (space)

A space between two selectors means "find the second one anywhere inside the first one".

<nav>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/blog">Blog</a></li>
  </ul>
</nav>
<p>Read our <a href="/faq">FAQ</a>.</p>
nav a {
  color: white;
  background-color: #37474f;
  padding: 6px 12px;
  text-decoration: none;
}

Only the links inside <nav> get the dark background and white text. The FAQ link in the paragraph stays as a normal blue link. The links are not direct children of <nav> (they are inside <ul> and <li>), but the descendant selector finds them at any depth.

The child selector (>)

The > combinator selects only direct children: one level down, not deeper.

<ul class="menu">
  <li>Starters
    <ul>
      <li>Soup</li>
      <li>Salad</li>
    </ul>
  </li>
  <li>Main dishes</li>
</ul>
.menu > li {
  font-weight: bold;
  color: #6a1b9a;
}

"Starters" and "Main dishes" are direct children of .menu, so they turn bold and purple. "Soup" and "Salad" are inside a nested list, deeper in the tree, so the rule does not select them.

Note: You might still see the nested items look bold. That's because some properties, like color and font-weight, are inherited: children copy them from their parent. Try border-bottom: 1px solid #ccc; instead, which is not inherited, to see the difference clearly.

The adjacent sibling selector (+)

The + combinator selects an element that comes directly after another one, with the same parent.

<article>
  <h2>How to Make Pancakes</h2>
  <p>Pancakes are quick and easy. Here is my family recipe.</p>
  <p>First, mix the flour and milk.</p>
  <p>Then, add one egg.</p>
</article>
h2 + p {
  font-size: 20px;
  color: #555;
}

Only the first paragraph, the one right after the heading, gets bigger gray text. This is a nice way to style an introduction without adding a class.

The general sibling selector (~)

The ~ combinator selects all siblings that come after an element, not just the next one.

h2 ~ p {
  margin-left: 20px;
}

With the same pancake HTML, all three paragraphs after the <h2> get indented. Siblings that come before the heading are not selected. Combinators only look forward and down, never back or up.

Keep your selectors short

You can chain combinators, like body main article section div p a. Please don't. Long selectors cause problems:

  • They break when you change the HTML structure.
  • They are stronger in the cascade, so they are harder to override later.
  • They are hard to read.

A good rule: use one or two levels at most. If you need more, add a class to the element instead.

/* Too long and fragile */
main article .content ul li a { color: teal; }

/* Better */
.content a { color: teal; }

Tip: When you are not sure what a selector matches, open DevTools, press Ctrl+F (Cmd+F on a Mac) in the Elements panel and type the selector. The browser highlights every match.

Practice exercise

Create a <div class="card"> containing an <h3>, two <p> elements and a <ul> with links. Then write CSS so that: only links inside the card are green; the paragraph right after the <h3> is italic; and only the direct <li> children of the list get a bottom border.

Hint: you need a descendant selector, a + selector and a > selector. For italic text use font-style: italic;.

Key takeaways

  • A space selects descendants at any depth: nav a.
  • > selects direct children only: .menu > li.
  • + selects the very next sibling: h2 + p.
  • ~ selects all following siblings: h2 ~ p.
  • Keep selectors short; add a class instead of writing long chains.