2

I want to define css that does apply to .b but not to .a .b

No hacks accepted in the manner of

.a .b {
   background-color: cornflowerblue;
}

Furthermore, the html can be in a arbitrary container. body > .b is as well not working for my case

I want to use the :not selector or an alternative solution that does not make me change the definition of .a .b

div {
  width: 50px;
  height: 50px;
  background-color: cornflowerblue;
  margin: 10px;
  border: 1px solid salmon;
}

.b {
  background-color: green;
}
<div class="a">
  <div class="b"></div>
</div>

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

see codepen here

https://codepen.io/anon/pen/OxOLZE

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Toskan
  • 13,911
  • 14
  • 95
  • 185
  • life hack https://codepen.io/anon/pen/PJOYgd – soft87 Oct 03 '17 at 21:28
  • just a side note, you don't want to do that since its very slow (Css doesn't support it for that reason), only if you know that .b is always directly inside an .a there is an answer with pure css already posted – Elentriel Oct 03 '17 at 21:41

1 Answers1

5

This will select all .b elements that are not children of .a.

div {
  width: 50px;
  height: 50px;
  background-color: cornflowerblue;
  margin: 10px;
  border: 1px solid salmon;
}

*:not(.a) > .b {
  background-color: green;
}
<div class="a">
  <div class="b"></div>
</div>

<div class="b"></div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • No, it will not select .a > .b. CSS is read by browsers right to left, so this rule is translated to, roughly: *:not(.a) > .b if there is an object with a class b, and directly above it is any object with class not a, the rules applies *:not(.a) .b this would translate: if there is an object with a class b, and above it is any object with class not a, the rules applies, which would apply if even one object above .b did not have .a as class – Elentriel Oct 03 '17 at 21:47
  • The question asks for not `.a .b`. Should the answer be `*:not(.a) .b`, in case `.b` is nested deeper within `.a`? – Hans Oct 04 '17 at 00:02
  • 1
    The descendent combinator won't work in this instance because `*:not(.a)` will be matched at least by the html element (unless it has class "a") so `*:not(.a) .b` will match all elements with class "b" even if there is an element with class "a" that is an ancestor of the element with class "b". For `*:not(.a) .b` to work, *all* ancestors of the element with class "b" would have to have the class "a". – Alohci Oct 04 '17 at 01:15
  • 1
    @Elentriel: What does RTL evaluation have to do with this? I could easily say "select any element that isn't .a and find its .b child" and it would mean exactly the same thing. – BoltClock Oct 04 '17 at 05:13