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:
- The Descendant Combinator (a space):
allows you to select elements that are descendants
(children, grand-children) of another element.
- The Child Combinator (a > symbol):
allows you to select elements that are children
(direct descendants, only) of another element.
- The Adjacent Sibling Combinator
(a + symbol): allows you to select an element that
is directly after another element.
- The General Sibling Combinator
(a ~ symbol): allows you to select multiple sibling
elements that appear after another element.
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).
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.
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)