0

Given this HTML:

<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
</div>

I would like a nice dingbat in place of very last horizontal rule, and a blank line for the first one.

However, consider this HTML:

<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>

Here, there should be a blank line for the hr, and no dingbat.

I was thinking I would put the dingbat in the content after each hr, then remove the content for any HR followed by a p:

hr {
  border: 0;
  text-align: center;
}
hr::after {
  content: "❧"
}

hr::after + p {
  content: "";
}

That last rule, of course, doesn't work. :)

How do I set the ::after content only when followed by a p? Or, is there a way to select only the last occurrence of the hr if it has no following element?

David Eyk
  • 12,171
  • 11
  • 63
  • 103
  • I would like some clarification; your first statement indicates you want the dingbat after the 2nd `p` (based on your HTML). Your second statement asks how to add a dingbat after *each* `p`. Your attempted code that you say doesn't work would place a dingbat only after the *1st* `p`. Which of these three scenarios are you looking to achieve? – TylerH Jan 11 '19 at 15:42
  • Yeah, sorry, that was confusing. I've clarified the question. – David Eyk Jan 11 '19 at 16:55

2 Answers2

4

Someone will point out to you, correctly, that there is no previous sibling selector, but you don't need one for this.

You can simply apply the dingbat to hr only when it's the last child like so:

div {
  margin-bottom: 1em;
  border: medium solid;
  padding: 0 0.5em;
}
hr {
  border: 0;
  text-align: center;
}
hr:last-child::after {
  content: "❧"
}
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>

<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <hr />
</div>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • OP's wording is a bit confusing to me, but `But I only want the dingbat to appear on the last hr in the div` sounds to me like the dingbat should be after the second `p`, not between the first and second. – TylerH Jan 11 '19 at 15:41
  • @TylerH: Huh. You're right. Yeah that is very confusing, based on how hr works you would expect the last one to be hidden if there's no content following it. But I'm gonna err on the side of caution and edit to follow exactly what's been asked... – BoltClock Jan 11 '19 at 15:43
  • are pseudo element allowed on hr? will this work everywhere? – Temani Afif Jan 11 '19 at 16:00
  • @Temani Afif: I remember reading something mentioning that most void elements can reliably have ::before and ::after pseudo-elements due to certain loopholes in how the DOM and CSS specs interact, but I don't remember what it was. – BoltClock Jan 11 '19 at 16:03
  • @Temani Afif: Not "most" void elements, but some, ones that are non-replaced elements. – BoltClock Jan 11 '19 at 16:07
  • I added a second example to further clarify. I *only* want the dingbat to appear on an `hr` that has no following sibling. With `:last-of-type`, the second HTML example still gets the dingbat. – David Eyk Jan 11 '19 at 17:00
1

You can simplify and only consider the p element without hr:

Not for the last

p:not(:last-child)::after {
  content: "❧";
  display:block;
  text-align:center
}
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>

Only for the last:

p:last-child::after {
  content: "❧";
  display:block;
  text-align:center
}
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415