Mdd
Mdd

Reputation: 4420

Select the first 3 sibling elements (<p>) of another element (<h2>)

How do I select all the <p> tags that are siblings to the first 3 <h2> tags using CSS?

The tags with the text "one", "two", "three" should be red but the text "four", and "five" should not be selected.

Here is my example code but I am not sure what that CSS selector should look like.

.container h2 + p {
  color: red
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

Upvotes: 2

Views: 885

Answers (3)

Amadan
Amadan

Reputation: 198418

EDITED due to question clarification:

As BoltClock says, there is no selector for that. But you can turn it around, and select all <p> after the fourth <h2> and make them not red:

.container p {
  color: red;
}
.container h2:nth-of-type(4) ~ p {
  color: inherit;
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

Upvotes: 1

BoltClock
BoltClock

Reputation: 724132

If you really have to select all the p elements that follow the first three h2 elements, you will have to use as many complex selectors as there are p elements that match that criteria — no two ways about it. Selectors doesn't provide a pseudo-class for matching n elements that follow another element, nor does it provide one for matching elements between two other elements (so you can't, for example, write a selector that matches all elements between h2:nth-of-type(3) and h2:nth-of-type(4)).

.container h2:nth-of-type(-n+3) + p,
.container h2:nth-of-type(-n+3) + p + p,
.container h2:nth-of-type(-n+3) + p + p + p {
  color: red
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

If overriding is not out of the question, then it becomes much, much easier — you can simply override it with a different selector instead:

.container h2 ~ p {
  color: red
}

.container h2:nth-of-type(4) ~ p {
  color: currentColor
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

Upvotes: 3

dippas
dippas

Reputation: 60573

use :nth-of-type()

snippet

.container h2:nth-of-type(-n+3) + p {
  color: red
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

To select ALL instead the adjacent p to h2 you need more complex selectors:

Snippet

.container h2:nth-of-type(-n+3) + p,
.container h2:nth-of-type(-n+3) + p + p,
.container h2:nth-of-type(-n+3) + p + p + p {
  color: red
}
<div class="container">
  <h2>Some text</h2>
  <p>One</p>
  <h2>Some text</h2>
  <p>Two</p>
  <p>Two</p>
  <h2>Some text</h2>
  <p>Three</p>
  <p>Three</p>
  <p>Three</p>
  <h2>Some text</h2>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <p>Four</p>
  <h2>Some text</h2>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
  <p>Five</p>
</div>

Upvotes: 2

Related Questions