4

I have an HTML page like this:

 <p></p>
 <p></p>
 <p></p>

 <div></div>

 <p></p>
 <p></p>
 <p></p>

 <div></div>

and this pattern continues.

Normally the div elements should not display so:

div{display:none;}

But when a paragraph is hovered, the first div element after that should be displayed:

p:hover+div{display:block;}

but this works only for the previous p . and this:

p:hover~div{display:block;}

shows all divs after the hovered p not just the first one after.

How could I display only the first non-adjacent div after the hovered p?

here is the demo

Actually I am looking for a selector like first-sibling.

Ormoz
  • 2,975
  • 10
  • 35
  • 50
  • Not sure if I understood the query. Are you looking at a way to display only the first `div` following the `p` tags? I am not sure if my answer is confirming with your need. – Harry Feb 27 '15 at 13:02
  • @Harry Thanks , your answer is the solution :) – Ormoz Feb 27 '15 at 13:15

4 Answers4

9

You should use the below setting:

p:hover ~ div ~ div {
    display:none;
}

This would set the display back to none for all div after the first div following the hovered paragraph.

div {
  display: none;
}
p:hover ~ div {
  display: block;
}
p:hover ~ div ~ div {
  display: none;
}
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d1</div>
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d2</div>
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d3</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
4

Have you tried using this:

div {
  display: none;
  background: blue;
  color: #fff;
}
p:hover+div,
p:hover+p+div,
p:hover+p+p+div {
  display: block;
}
<p>lorem</p>
<p>lorem</p>
<p>lorem</p>

<div>Ipsum</div>

<p>lorem</p>
<p>lorem</p>
<p>lorem</p>

<div>Ipsum</div>
Aaron
  • 10,187
  • 3
  • 23
  • 39
  • Useful obviously if the actual structure is **only** 4 paragraphs and a div otherwise it's very inflexible. – Paulie_D Feb 27 '15 at 12:58
  • But the OP said this will follow that structure? – Aaron Feb 27 '15 at 12:59
  • Actually he said "like" this...not that it was the precise structure. If there were 12 paragraphs and then a div you'd have a lot of `+p` statements. I'm not saying your answer is wrong...just that it's limited. – Paulie_D Feb 27 '15 at 13:00
  • I thought there is some selector like `first-sibling-after` . Is there anything like that? – Ormoz Feb 27 '15 at 13:04
  • 1
    @Aaron: You can't really blame him. Too often we answer questions only for the asker to change their markup later in a way that invalidates the answer because we made too many assumptions about the original markup. – BoltClock Feb 27 '15 at 13:09
4

There is no "first-sibling" selector, but you can override the style for subsequent div elements using the same technique described in this answer:

div, 
p:hover ~ div ~ div {
    display: none;
}

p:hover ~ div {
    display: block;
}

This is preferred if you do not know the maximum number of p elements that can separate div elements in advance, or you would rather not have to hardcode all the adjacent selectors necessary as shown in Aaron's answer.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • thank you very much. Actually, by the time being, the number of paragraphs between `div`s are known, But who knows? maybe in the future the `HTML` change, so I prefer this general answer. – Ormoz Feb 27 '15 at 13:27
0

I would place your blocks between section tags. Then <p> tags and <div> tag are siblings from the same element. Also if these tags belong to each other its also good to reflect this in your markup.

JSFIDDLE DEMO

<section>
 <p>hello</p>
 <p>world</p>
 <p>bar</p>

 <div></div>
</section>

<section>
 <p>hello</p>
 <p>world</p>
 <p>bar</p>

 <div></div>
</section>

css

section p:hover~div{display:block;}
kasper Taeymans
  • 6,950
  • 5
  • 32
  • 51