1

I have a HTML structure as follows, with repeating pairs of img and p tags. In many cases, the img is not present.

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

I wish to select all p tags that are not immediately preceded by an img.

I can select p tags that are preceded by img:

img + p {}

How do I select the inverse? - ie, p tags that are not preceded by img?

snazzybouche
  • 2,241
  • 3
  • 21
  • 51

2 Answers2

2

Being that there isn't a "previous sibling" selector, you could style your standard p elements, and then overwrite the ones that are preceded by an img with the default styling.

You're probably better off wrapping this in a container though, just so you're not styling every p on the page.

.container > p {
  color: red;
}

.container > img + p {
  color: black;
}

/* DEMO PURPOSES */
img { display: none; } img, p { margin: 0; }
<div class="container">
    <img />
    <p>This is preceded by img</p>
    <img />
    <p>This is preceded by img</p>
    <img />
    <p>This is preceded by img</p>
    <p>This is not preceded by img</p>
    <p>This is not preceded by img</p>
    <img />
    <p>This is preceded by img</p>
</div>
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
2

Till the point that I am writing this answer, CSS doesn't provide a selector for the previous element.

For your case, and as a workaround, let's say that these p and img tags are placed in a wrapping div.wrapper, consider trying this:

.wrapper > img + p ~ p {
   color: red;
}
.wrapper > img + p {
   color: black !important;
}
    <div class="wrapper">
 <img style="height:20px;display:block;" src="http://via.placeholder.com/350x250" />
 <p>unaffected</p>
 <p>affected</p>
 <p>affected</p>
 <img style="height:20px;display:block;" src="http://via.placeholder.com/350x250" />
 <p>unaffected</p>
 <p>affected</p>
 <img style="height:20px;display:block;" src="http://via.placeholder.com/350x250" />
 <p>unaffected</p>
</div>

Hope I pushed you further.

ThS
  • 4,597
  • 2
  • 15
  • 27