santa
santa

Reputation: 12512

Select element not followed by another

I need to be able to select an HTML p tag , ONLY if it is not followed by another div element with particular class. For example, I will need to select this P

<div id="myContainer">
    <p>...</p>
    <div>...</div>
</div>

but not this, because it is followed by a div with class="red".

<div id="myContainer">
    <p>...</p>
    <div class="red">...</div>
</div>

Here's what I'm attempting:

#myContainer > p ~ div:not(.step) 

Upvotes: 8

Views: 11667

Answers (3)

Arbel
Arbel

Reputation: 30989

Update in 2023:

It is now possible to use the :has() (ref) pseudo-class as a way of selecting a parent element or a previous sibling element with respect to a reference element by taking a relative selector list as an argument.

Note that some browsers may still not support this. As of this writing, Chrome and Safari already support this. With Firefox, it's in development and is supported in a pre-release version.

So the following will achieve what the question is asking:

.myContainer p:has(+ div:not(.red)) {
    border: 1px solid #000;
  }

DEMO https://jsfiddle.net/fzya5eLd/


Original answer in 2014:

You can't use CSS to target previous elements, but based on your HTML structure you can use immediate sibling selector.

CSS:

.myContainer p + div:not(.red)   {
   border: 1px solid #000;
}

HTML:

<div class="myContainer">
    <p>...</p>
    <div>...</div>
</div>
<div class="myContainer">
    <p>...</p>
    <div class="red">...</div>
</div>

DEMO http://jsfiddle.net/92VVZ/

Upvotes: 7

robertspierre
robertspierre

Reputation: 4351

Given the following HTML code:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <title>Test page</title>
  </head>
  <body>
    <div id="myContainer">
      <p>P1</p>
      <div>D1</div>
  </div>
  <div id="myContainer">
      <p>P2</p>
      <div class="red">D2</div>
  </div>
  </body>
</html>

The CSS selector:

p:not(:has(+div.red))

will select the first p but not the last one.

Explanation:

  • The :not() pseudo-class represents an element that is not represented by its argument (link)
  • The :has() pseudo-class (link) represents an element that matches the selector in its argument when anchored against that element. This pseudo-class works since Chrome >= 105 (released august 30, 2022) while, as of December 2023, it has yet to be released in Firefox(link)
  • The next-sibling combinator + selects the next sibling of an element (link)

All other answers are wrong as they select the div element, not the previous p element.

Upvotes: 1

kei
kei

Reputation: 20481

Is this what you mean? Then you're almost there.

DEMO

/* will select p not directly followed by div.red */
#myContainer > p + div:not(.red) 

Upvotes: -3

Related Questions