10

Using CSS and the following example, is there a way to select only <p>'s that are followed by <ul>'s?

If not, what is the jQuery selector, or would it require an if statement?

<p>Hello there.</p>

<p>Select this para!</p>
<ul>
    <li>list item</li>
</ul>

<ul>
    <li>don't select this list! :)</li>
</ul>

<p>And don't select this paragraph! :)</p>
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
jonathanbell
  • 2,507
  • 5
  • 23
  • 40

6 Answers6

14

It's not possible in CSS3, the best you can do is select only the <ul> which follow <p>:

p + ul { /*...*/ }

However it will be possible when browsers start implementing the CSS4 subject operator:

!p + ul { /*...*/ }

In the meantime, you'll have to use jQuery and walk the DOM back.

robertc
  • 74,533
  • 18
  • 193
  • 177
6

No, actually CSS won't help you in this.

What you need would be a Previous Sibling Selector, that does not exist.

Take a look at this too: Is there a "previous sibling" CSS selector?

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
6

Unfortunately, you are going to need to turn to javascript. The closest CSS selector to what you want (adjacent sibling selector) would do the exact opposite of what you want. For example, you could select all <ul> after a <p> like this:

p + ul { //style }

You can however make this selection in jQuery like this:

$('p + ul').prev('p')

So you first select all <ul> immediately after <p> and then select the previous <p> from them.

Mike Brant
  • 70,514
  • 10
  • 99
  • 103
2

http://api.jquery.com/prev/

Would something like this work for you? you might have to add a class to P's,

but it should allow you to select every class selected element before Uls

Example:

<p class="selected">my p</p>
<ul>My ul</ul>
<script>$("ul").prev(".selected").css("background", "yellow");</script>
</body>
IanO.S.
  • 1,362
  • 1
  • 10
  • 20
2

You could also stick an empty span before the p thats before the ul and select that:

span + p {
margin-bottom: 0;
}
David Provost
  • 317
  • 2
  • 11
0

use the :not/:has selector (doesn't however have wide support)

<div>
   <span>first</span>
   <span>second</span>
</div>

div span:not(:last-of-type){
  border: 1px solid red;
}


p:has(+ ul){
  display: block;
  border: 1px solid blue;
}
<div>
<span>first</span>
<span>second</span>
</div>


<div>
<p>Hello there.</p>

<p>Select this para!</p>
<ul>
    <li>list item</li>
</ul>

<ul>
    <li>don't select this list! :)</li>
</ul>

<p>And don't select this paragraph! :)</p>
</div>