1

I would like to create a rule for certain elements which only affects an element if it has none of a list of classes.

My attempt:

div:not(.a, .c) {
  color: red;
}
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>

If you run this snippet, it obviously does not work as intended. Seems the selector is invalid and does not affect any div whatsoever.

Next I tried chaining :not() which seems very clumsy, but works:

div:not(.a):not(.c) {
  color: red;
}
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>

Is this the only way to solve the given problem?

connexo
  • 53,704
  • 14
  • 91
  • 128
  • 4
    Selector lists are only supported by Safari, so yes, chaining is the only way to do it currently. https://developer.mozilla.org/en-US/docs/Web/CSS/:not#Browser_compatibility – Turnip Jan 08 '20 at 10:01
  • Does this answer your question? [Can I write a CSS selector selecting elements NOT having a certain class or attribute?](https://stackoverflow.com/questions/9110300/can-i-write-a-css-selector-selecting-elements-not-having-a-certain-class-or-attr) – T04435 Jan 08 '20 at 10:27
  • @T04435 Obviously it does not. – connexo Jan 08 '20 at 10:29
  • Are you on plain css or you got a preprocessor scss, less ...? – T04435 Jan 08 '20 at 11:10
  • @T04435 Plain CSS. – connexo Jan 08 '20 at 12:12
  • @Turnip If you add that as an answer, I'll pick it. – connexo Jan 08 '20 at 12:13
  • you should note that both selectors will select the same elements (even if the first one is still not supported and will be released in the Level 4: https://drafts.csswg.org/selectors-4/#selector-list) but they will not have the same specificity, the last one is more specific than the first (related: https://stackoverflow.com/a/59364095/8620333) – Temani Afif Jan 08 '20 at 12:21

2 Answers2

1

Chaining the :not() selector in CSS is the only way at present (in Jan 2020) to indicate a logical AND operator.

So, yes:

div:not(.a):not(.c)

is the correct way to write:

div:not(.a) AND div:not(.c)

div:not(.a):not(.c) {
  color: red;
}
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
Rounin
  • 27,134
  • 9
  • 83
  • 108
0

I think by your question you always know the classes you don't want to change the styles for. So assuming that this is my take at it.

.all {
  /** give default styles to all elements */
  color: red;
}

.a,
.c {
  /** then reset the ones you where targeting with :not():not()... */
  color: black;
}
<div class="all a">a</div>
<div class="all b">b</div>
<div class="all c">c</div>
T04435
  • 12,507
  • 5
  • 54
  • 54