Combinators
Prerequisites: Basic selectors
Combinators select elements by their relationship to other elements in the DOM tree.
| Combinator | Example | Selects |
|---|---|---|
| descendant (space) | nav a |
every a anywhere inside a nav |
child > |
ul > li |
lis that are direct children of a ul |
next sibling + |
h2 + p |
a p immediately after an h2 |
subsequent sibling ~ |
h2 ~ p |
every p after an h2, with the same parent |
<style>
.menu a { color: blue; }
.menu > li { font-weight: bold; }
h2 + p { font-size: 1.25rem; }
h2 ~ p { color: gray; }
</style>
<ul class="menu">
<li><a href="/">Home</a>
<ul>
<li><a href="/team">Team</a></li>
</ul>
</li>
</ul>
<h2>Title</h2>
<p id="p1">First paragraph</p>
<p id="p2">Second paragraph</p>
<script>
const show = sel => {
const s = getComputedStyle(document.querySelector(sel));
console.log(sel.padEnd(22), s.color, s.fontWeight, s.fontSize);
};
show(".menu > li");
show(".menu li li");
show(".menu li li a");
show("#p1");
show("#p2");
</script>
.menu > li rgb(0, 0, 0) 700 16px
.menu li li rgb(0, 0, 0) 700 16px
.menu li li a rgb(0, 0, 255) 700 16px
#p1 rgb(128, 128, 128) 400 20px
#p2 rgb(128, 128, 128) 400 16px
- Both links are blue:
.menu areaches any depth. - The nested
liis bold too, even though.menu > lionly matches the outer one —font-weightis inherited from its bold parent. Selectors pick elements; inheritance then passes some values down. - The first paragraph after the
h2is larger; both are gray.
Keep selectors short
body div.content ul.list > li a works, but it's fragile (it breaks
when the HTML changes) and hard to override. Prefer a class on the thing
you want to style: .list-link.
Practice
Style only the paragraphs that are direct children of an article, and
remove the top margin from any element that immediately follows an h1.
Show solution
article > p {
line-height: 1.7;
}
h1 + * {
margin-top: 0;
}