Overview of This Lesson

Sometimes you'll want to select HTML elements to style based on more than just the element name, class name, or ID. For example, What if you want to style links inside <nav> elements to look like buttons or a menu, but you don't want those styles to affect all the other links in the document? What if you wanted a header's navigation to appear different from the footer's navigation? What if you had a page full of <article> elements, and you wanted the article directly under the <header> to have a different style, to make it stand out as the "newest"? All of this can be accomplished with combinators.

Combinators are special symbols used in a CSS selector that allow you to select elements with a relationship to another element or set of elements. For example, styling only those <a> elements that are nested inside <nav> elements, or styling only the <article> that is right after the <header> element. Combinators allow you to create more complex selectors that give you more flexibilty over which elements a rule applies to.

Understanding the combinators requires that you have a very basic understanding of the HTML DOM, which is covered in the Fundamentals of HTML Tutorial.

The combinators CSS are:

Pre-Requisites

Make sure that you've worked through all of the previous lessons on CSS: you should be familiar with the basic syntax of CSS, class selectors and ID selectors, and be familiar with some basic properties, such as those from the Box Model.

Descendant and Child Combinators

Descendant and Child combinators allow to select elements that are nested inside other elements. The difference between descendants and children is that descendants can be children, grand-children, great-grand-children, etc. In other words, elements that are nested inside a container element, and any of the nested elements' children, and any of those elements' children, etc. A child element refers to only the elements nested directly inside another element; it doesn't include any children of those nested elements.

For example, in the code below, the <article> has 4 children ("A paragraph..", "Another paragraph..." , the <aside> element, and "The last paragraph..."). The elements that are children of the <aside> - the <div> containing the image, plus the "Cool and interesting.." paragraph - are descendants of the <article> element.

<article>
  <h2>An Article About Something</h2>

  <p>A paragraph introducing something this article 
    is about.</p>
  <p>Another paragraph that elaborates on something.</p>
  <aside>
    <div>
      <img src="some/icon.png" alt="random icon">
    </div>
    <p>Cool and interesting side-note about something.</p>
  </aside>
  <p>The last paragraph.</p>
</article>

Descendant Combinator

The descendant combinator allows you select any of the elements that are descendants of another element. In the code example above, you could use a descendant combinator to select every single <p> paragraph element inside the <article> - this would not only include the 3 paragraph elements that are children of the article, but it would also include the paragraph that's inside the <aside> element.

The descendant combinator symbol is the space character. For example, this rule styles all paragraph descendants of SECTION elements so that those paragraphs' content have a larger font size and a different text colour:

See the Pen Descendant Selector Example by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the descendant combinator example CodePen, opens in the pen tab)

This CodePen demonstrates which items are selected using a descendant selector and which aren't. Notice that the paragraphs outside the section elements are not affected, but all the paragraphs inside the sections are. Even the paragraphs that are nested inside the <aside> elements (which are nested inside the <section> elements) are affected: those are also descendants (you could call them grand-children). They're not direct descendants, but they're still descendants.

Try the exercises in this CodePen:

See the Pen Try Me 1: Descendant by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the descendant combinator exercise CodePen, opens in the pen tab)

Check your Solution (opens in the pen tab).

Child Combinator

The child combinator allows you to select children (direct descendants, only) of an element. In other words, they select an element's children, but none of that element's grand-children.

The child combinator is the > (greater-than) symbol. In the example below, only paragraphs that are direct children of the section elements are styled with a larger font size and a different text colour. All other paragraphs inside and outside of the SECTION elements are unaffected.

See the Pen Child Selector Example by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the child combinator example CodePen, opens in the pen tab)

You can see this in action in the above CodePen, a variation of the previous one. Notice that all I did was turn the descendant selector into a child selector. Now the only paragraphs affected are the ones that are direct children of the SECTION elements: the paragraphs inside the ASIDE elements are not affected.

Try the exercises in this CodePen:

See the Pen Try Me 2: Child (solution) by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the child combinator exercise CodePen, opens in the pen tab)

Check your Solution (opens in the pen tab).

Exercise

The instructions are in the CSS tab of the CodePen below. Make sure you read the code in both the HTML and CSS tabs.

See the Pen Combinators: Exercise 1 by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the child/descendant combinators exercise CodePen, opens in the pen tab)

Check your Solution (opens in the pen tab).

Sibling Combinators

There are 2 sibling combinators: the Adjacent sibling combinator and the General sibling combinator.

The adjacent sibling combinator uses the + (plus) symbol and is used to select the next sibling of an element (i.e. an element that is immediately after/beside another element), as long as both elements have the same parent element.

Note that if you're looking at code, it appears as if the next sibling is below the main element in the source:

<figure>
  <img src="aPicture.jpg" alt="a picture of a thing">
  <figcaption>Some stuff in a figure</figcaption>
<figure>

Here, the FIGCAPTION is the next sibling of the IMG - in the code, the FIGCAPTION is below the IMG.

In a DOM tree, sibling nodes appear side-by side, so the node immediately beside another node is a sibling, as long as both nodes descend from the same parent.

For example:

See the Pen Adjacent Sibling Selectors by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the adjacent sibling combinator example CodePen, opens in the pen tab)

In the example above, there is 1 paragraph before the FIGURE element and 2 paragraphs after the FIGURE element. The first CSS rule for P, IMG, and FIGURE elements state that they all have a bit of margin space on all four sides. The second CSS rule indicates that any P element immediately after a FIGURE element in the same container should have a larger top margin, instead of the smaller margin defined earlier.

Only the paragraph directly under the FIGURE element is affected: it's the FIGURE element's adjacent sibling. The paragraph above the figure and the second paragraph after the figure do not get the 10 pixels of margin space, because they are not adjacent siblings.

The general sibling combinator uses the ~ (tilde) symbol and it affects all sibling elements after another element, as long as all the elements are in the same parent container. Note that it only affects the siblings after the element; it doesn't affect siblings before the element. For example:

See the Pen General Sibling Selectors by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the general sibling combinator example CodePen, opens in the pen tab)

Notice that only the paragraph elements below the figure inside the first section are affected. The paragraphs before the figure are not affected. Nor are any of the paragraphs inside the other section on the page, because they have a different parent element.

Exercise

The instructions are in the CSS tab of the CodePen below. Make sure you read the code in both the HTML and CSS tabs.

See the Pen Combinators: Exercise 2 by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the general sibling combinator exercise CodePen, opens in the pen tab)

When done correctly, the following paragraphs will show up with bold text:
"This doesn't mean cats like baths."
"Regardless, cats will sleep anywhere they feel safe."
"Many suspect that some cats only look like they're sleeping, but they're really awake, busy plotting their next evil deed."

Also, the following paragraphs will be purple:
"Cats will hide in and under things."
"Some cats will mess up your bed covers."

Check your Solution (opens in the pen tab).

Combining Combinators

You can even combine combinators with each other or with other kinds of selectors. For example, how would you style a <span> that is a descendant of an <aside>, but only when the <aside> is a child of an <article>? What if you wanted to style only the <aside> elements that are children of any element with class="combo"? The following CodePen shows you some ways you can combine combinators with each other, or with other types of selectors:

See the Pen Combining Combinators by Wendi Jollymore (@ProfWendi) on CodePen.

(direct link to the combining combinators example CodePen, opens in the pen tab)