Combinators, Revisited

Master descendant, child, and sibling combinators for surgical, class-light selection.

You already met the four combinators. Now let's talk about when to reach for each one, because used well they let you write far fewer classes and keep your markup clean.

The four relationships

  • A B — any B nested anywhere inside A. Powerful, but greedy.
  • A > B — only direct children. This is the one that saves you from accidental cascades into nested components.
  • A + B — the single element immediately after A. Perfect for “space between adjacent things”.
  • A ~ B — every following sibling, not just the next.

The lobotomized owl

One of the most quietly brilliant selectors ever written is * + *. It reads “any element that follows any element” — in other words, everything except the first child. It's the classic way to add rhythm to a stack without touching the first or last item:

.stack > * + * {
  margin-block-start: 1rem;
}

No trailing margin, no :first-child reset, no fuss. That's the mark of a combinator used with intent.

Example

Try it yourself
Loading editor…
Press Run to see the result.

When to use it

  • A developer uses the general sibling combinator (.error ~ .hint) to show a hint paragraph only when an error element precedes it.
  • A developer uses the child combinator (.menu > li > a) to style top-level nav links without accidentally styling links inside nested sub-menus.
  • A designer uses the adjacent sibling combinator (h2 + p) to remove the top margin from the first paragraph after each section heading.

More examples

Child combinator for direct-only styles

Uses > to style only direct list children of .nav while leaving deeply nested sub-menu items in their own block flow.

Example Β· css
/* Only direct li children, not nested ones */
.nav > li {
  display: inline-block;
  position: relative;
}

/* Nested sub-items are unaffected */
.nav li li {
  display: block;
}

Adjacent sibling for post-heading spacing

Targets the single paragraph immediately following an h2 to remove its top margin and de-emphasize it as a subtitle.

Example Β· css
h2 { margin-bottom: 24px; }

/* Remove extra top space from the first p after h2 */
h2 + p {
  margin-top: 0;
  color: #555;
  font-size: 1.1rem;
}

General sibling for conditional visibility

Uses the ~ general sibling combinator to reveal a .hint element whenever a .field-error sibling is present in the DOM.

Example Β· css
.field-error {
  display: none;
}

/* Show hint whenever an error is present anywhere after .form-group */
.field-error ~ .hint {
  display: block;
  color: #888;
  font-size: 0.85rem;
}

Discussion

  • Be the first to comment on this lesson.
Combinators, Revisited β€” CSS | SoundsCode