The cascade

Combinators

Target descendants, direct children, adjacent siblings, and general siblings without adding a class to every element.

Sometimes you want to style an element based on where it sits in the HTML, not on its own class. Combinators let you do that. They describe a relationship between two selectors.

There are four of them:

.card p { }
.card > p { }
h2 + p { }
h2 ~ p { }
  • A space is the descendant combinator. .card p matches any p inside a .card, at any depth.
  • > is the child combinator. .card > p matches only paragraphs that are direct children of the card.
  • + is the adjacent sibling combinator. h2 + p matches a p that comes right after an h2, with the same parent.
  • ~ is the general sibling combinator. h2 ~ p matches every p that comes after an h2 under the same parent, not just the first one.

Descendant vs child

The descendant combinator is the one people reach for first, and it reaches further than you think. Say a card contains a blockquote with a paragraph inside it. .card p styles that quoted paragraph too. So does a nested card inside a card.

My rule: use the narrowest relationship your HTML guarantees. If the paragraphs you care about are always direct children, write .card > p. It stops at the first level and leaves nested content alone.

Siblings for spacing

Sibling combinators shine when spacing or emphasis depends on document order:

h2 + p {
  font-size: 1.125rem;
}

.field + .help {
  margin-block-start: 0.5rem;
}

The first rule makes the paragraph right after a heading a bit larger, a common “lead paragraph” effect. The second adds space above help text only when it directly follows a form field. Neither needs an extra class in the HTML. The order of the elements already carries the information.

Don’t build long chains

You can chain combinators as much as you want. Please don’t:

main .page section .card p strong { }

This selector only works while the HTML has exactly that shape. Move the card into an aside and the styling disappears. It also has a high specificity, which makes it painful to override later.

When you feel the urge to write a chain like that, add a class to the element instead. .card-highlight is easier to read, easier to find, and survives HTML changes.

Try this on the course page. Copy one of the cards and paste it inside another card. Then compare .card p and .card > p in DevTools and see which paragraphs each one lights up. The nested one is where the difference shows.

Lesson completed