47

Consider the following html:

<div>
    <div class="iwant" />
    <div class="idontwant" />
</div>
 <div>
    <div class="iwant" />
</div>

I'm interested in a selector (for crawling content so I can't modify html) that would select all iwant that DO NOT have sibling with class idontwant.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Chris Hasiński
  • 2,965
  • 2
  • 25
  • 34

5 Answers5

75

There is no sibling selector to match elements (or not) by class.

The closest selector I can think of is

.iwant:only-child

But this selector means that there cannot be any other elements besides that div class="iwant" as children of the parent div, regardless of type or class. This may fulfill your need depending on the structure of your HTML though, so it's worth a try. If class names are a problem for you, though, then there probably isn't much of a solution, because there isn't an :only-of-class pseudo-class in CSS which filters by class and ignores the rest.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
6

If anyone still needs this, I found this answer . Based on it and on :not pseudo-class, the initial requirement can be accomplished using something like:

div:not(:has(+ .idontwant)) .iwant { 
  ... 
}

This approach has an advantage over the general sibling combinator: It also matches backwards, meaning something like:

<div>
    <div class="idontwant" />
    <div class="iwant" />
</div>

(so if you have the .idontwant element first -> case which would be ignored by the general sibling combinator)


Explanation:

  1. div:has(+ .idontwant) would match any div that has a direct sibling with the class idontwant
  2. div:not(:has(+ .idontwant)) matches any div that doesn't have a direct sibling with class idontwant
  3. All is left to do is search in the div that doesn't have a direct sibling with class idontwant for the class we want.

The selector is quite weird and big, but does the job, and I think there are (specific) cases where is quite needed.

Berci
  • 2,876
  • 1
  • 18
  • 28
5

There's no good way to target an item without a specific sibling item. But you can use .iwant:last-child to target items that doesn't have a subsequent sibling.

Example: http://codepen.io/martinkrulltott/pen/YyGgde

Martin
  • 1,916
  • 2
  • 25
  • 37
4

There's no negative-sibling CSS selector. Use the sibling selector to set new styles, then reset the styles at the .idontwant:

div.iwant {
    /*Set CSS here*/
    display: inline;
}
div.iwant ~ div.idontwant {
    /*Reset CSS*/
    display: block /* Default of DIV is block*/
}
Rob W
  • 341,306
  • 83
  • 791
  • 678
0

This also might be helpful - if the element you want is always last-child:

div:last-child:not(.idontwant) {

}
Denis Khay
  • 3,510
  • 1
  • 10
  • 6