jonathanbell
jonathanbell

Reputation: 2637

How to use CSS to select an element only if a specific element comes after the one you want to select?

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>

Upvotes: 10

Views: 13146

Answers (6)

user1347190
user1347190

Reputation: 31

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>

Upvotes: 0

David Provost
David Provost

Reputation: 437

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

span + p {
margin-bottom: 0;
}

Upvotes: 2

robertc
robertc

Reputation: 75707

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.

Upvotes: 14

Mike Brant
Mike Brant

Reputation: 71384

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.

Upvotes: 6

IanO.S.
IanO.S.

Reputation: 1382

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>

Upvotes: 2

Andrea Ligios
Andrea Ligios

Reputation: 50203

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?

Upvotes: 6

Related Questions