4

I'm trying to select only the divs with class c, that have at least one sibling with class b. Here are some examples:

// Case1
<div class="a"> 
    <div class="b"></div>
    <div class="b"></div>
    <div class="b"></div>
</div>

// Case2
<div class="a"> 
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
</div>

// Case3
<div class="a">
    <div class="b"></div>
    <div class="c"></div> //this one
    <div class="b"></div>
</div>

// Case4
<div class="a">
    <div class="c"></div> //this one
    <div class="b"></div>
    <div class="c"></div> //this one
</div>

I tried the following rule:

.a > .b ~ .c {
  background-color: red;
}

It works for case 1 - 3 but in the fourth example the first div with class c is not selected. AFAIK there is no other selector that would help me, so I'm trying my luck here.

PS: The div with class a can have more then 3 children. These are just examples and not actual use cases.

m4n0
  • 29,823
  • 27
  • 76
  • 89
Lucas
  • 357
  • 3
  • 15

2 Answers2

5

You cannot match an element that comes before a sibling element because there is no previous sibling selector, nor can you match a child element of a parent element that contains some other child element because there is no parent-of selector. You're going to need some other workaround that is not based on a selector.

Don't count on this being possible in selectors-4 unless you use JavaScript to match and apply a utility class to those .c elements — in which case you can do that today by taking advantage of jQuery's long-standing implementation of :has() (which I just wrote about earlier today):

$('.a:has(> .b) > .c')
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • As with everything in jQuery, this selector can be reproduced in vanilla JS which may be favorable if jQuery is not already being used – Zach Saucier Apr 05 '16 at 15:59
0

If you want to use CSS only and you have access to the server side code, you could just add an extra class like .contains-b to the parent elements or a data-attribute like data-contains="b" and use it as a selector.

.a[data-contains~=b]  .c {
  background-color: red;
}
<div class="a" data-contains="b">
  <div class="b"></div>
  <div class="b"></div>
  <div class="b"></div>
</div>

<div class="a" data-contains="c">
  <div class="c"></div>
  <div class="c"></div>
  <div class="c"></div>
</div>

<div class="a" data-contains="b c">
  <div class="b"></div>
  <div class="c">this one</div>
  <div class="b"></div>
</div>

<div class="a" data-contains="b c">
  <div class="c">this one</div>
  <div class="b"></div>
  <div class="c">this one</div>
</div>
xpy
  • 5,481
  • 3
  • 29
  • 48