1

I would like to be able to select all elements of class zz that are descendants of an element of class xx but not a descendant of class yy.

Consider the following:

<div class="xx">
  ... arbitrary depth ...
    <div class="zz" id="1">
    </div>

    <div class="yy">
       <div class=zz" id="2">
       </div>
    ...
    </div>
...
</div>

The selector I'm looking for would in the above case return the id1 element but not id2 element.

peterh
  • 18,404
  • 12
  • 87
  • 115

3 Answers3

1

Will this work for you?

Hopefully it is less complicated to combine a few :not() than to do a bunch of set/reset rules.

:not(.yy):not(body) > .zz { color: red }
<div class="xx">
  ... arbitrary depth ...
    <div>
      <div class="zz" id="1a">1a
      </div>
    </div>
  
    <div class="zz" id="1b">1b
    </div>

    <div class="yy">
       <div class="zz" id="2">2
       </div>
    </div>
</div>
<div class="zz" id="3">3
</div>

The second best, and if I were you, would be to add an extra div for your arbitrary elements, to match the .yy class in depth.

If that is possible, then the .xx :not(.yy) .zz { ... } rule that fcalderan suggests will work

.xx :not(.yy) .zz { color: red }
<div class="xx">
  <div>
    
      ... arbitrary depth ...

    <div>
      <div class="zz" id="1a">1a
      </div>
    </div>

    <div class="zz" id="1b">1b
    </div>
    

  </div>
  <div class="yy">
    <div class="zz" id="2">2
    </div>
  </div>
</div>
<div class="zz" id="3">3
</div>
Community
  • 1
  • 1
Asons
  • 84,923
  • 12
  • 110
  • 165
  • 1
    Nope. It will select also those zz's that are not descendants of xx. I've updated your brilliant example and added item3. Item3 *shouldn't* be selected. – peterh Feb 16 '16 at 18:55
  • @peterh You can combine `:not()` ... updated my answer – Asons Feb 16 '16 at 19:00
  • I've given you an upvote for trying. :-) Unfortunately I do not have control over the HTML as you may have guessed. Both of your solutions carry implicit assumptions with them. These assumptions are not true in my case. – peterh Feb 16 '16 at 22:06
0

I don't think you can write a selector like that which works in a general case.

However, you can use

.xx .zz {
  /* Some styles */
}
.yy .xx .zz, .xx .yy .zz { /* Or maybe just `.yy .zz` */
  /* Undo previous styles */
}

Of course, this requires knowing the styles of .xx .zz elements before the first ruleset applies.

Oriol
  • 274,082
  • 63
  • 437
  • 513
0

this is for only your scenario. based on your given html structure.

.xx > .zz {}

but this is only select immediate child "zz" class of "xx" class

Jay Patel
  • 5,783
  • 1
  • 17
  • 20