1

I'm trying to style all div elements except those in two different class groups. Everything I've tried doesn't seem to work.

The below test code should make the div with "test" text content be orange, but none of the selectors work.

div {
  height: 40px;
  width: 100px;
  background: cyan;
  display: inline-block;
}
div:not(.ZoomBar):not(.row.heading) {
  background: orange;
}
div:not(.ZoomBar, .row.heading) {
  background: orange;
}
div:not(.ZoomBar),
div:not(.row.heading) {
  background: orange;
}
<div class="ZoomBar">ZoomBar</div>
<div class="row heading">Heading</div>
<div>Test</div>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Jamie Barker
  • 8,145
  • 3
  • 29
  • 64

3 Answers3

2

You can use something like this

You cannot add unfortunately multiple class in a single not selector.

div {
  height: 40px;
  width: 100px;
  background: cyan;
  display: inline-block;
}

 

div:not(.ZoomBar):not([class="row heading"]){
  background: orange;
}
<div class="ZoomBar">ZoomBar</div>
<div class="row heading">Heading</div>
<div class="heading">Heading</div>
<div>Test</div>
viper
  • 539
  • 1
  • 4
  • 16
  • It's elements that have class row AND heading... that will be row OR heading :( – Jamie Barker Jun 12 '15 at 10:03
  • See again. Now it should work with div:not(.ZoomBar):not([class="row heading"]) – viper Jun 12 '15 at 10:27
  • Cynthia's answer is one step ahead. Technically it works, though it's just not future proof. – Jamie Barker Jun 12 '15 at 10:30
  • 1
    Perhaps then you would like to invert that logic and put the color on these classes and by default have orange on all the other ones. Not sure what you're trying to build though – viper Jun 12 '15 at 10:33
1

The answer is this:

div {
  height: 40px;
  width: 100px;
  background: cyan;
  display: inline-block;
}
div:not([class*="ZoomBar"]):not([class*="row heading"]):not([class*="heading row"]) {
  background: orange;
}

https://jsfiddle.net/ars9fL56/5/

Cynthia Sanchez
  • 178
  • 1
  • 9
1

The problem with :not() is that it only allows one simple selector at a time. This means any of :not(div), :not(.ZoomBar), :not(.row) and/or :not(.heading). It does not accept either

  • a compound selector, .row.heading, which consists of two class selectors; or
  • a comma-separated list of multiple selectors, .ZoomBar, .row.heading.

It's worth noting however that the selectors you've tried will work in jQuery, though not CSS.

Your problem is compounded (heh) by the fact that you're looking for both kinds of exclusions in a single rule. But it's still doable; it simply means you'll need to write a slightly more convoluted rule, with two selectors to account for the two class selectors in .row.heading:

div {
  height: 40px;
  width: 100px;
  background: cyan;
  display: inline-block;
}
div:not(.ZoomBar):not(.row),
div:not(.ZoomBar):not(.heading) {
  background: orange;
}
<div class="ZoomBar">ZoomBar</div>
<div class="row heading">Heading</div>
<div class="heading row">Heading</div>
<div class="heading foo row">Heading</div>
<div class="heading">Heading</div>
<div>Test</div>

If these are the only possible combinations of class names, you might be able to get away with simply excluding div elements with a class attribute using div:not([class]), but based on your question I suspect that this isn't the case.

For instance, notice in the above snippet that the div[class="heading"] element matches div:not(.ZoomBar):not(.row), and is therefore colored orange. If you may have elements with either class name but not both, those elements will be accounted for.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • This... this works! I know it works in jQuery because I've used it before. I actually read [an article](http://kilianvalkhof.com/2008/css-xhtml/the-css3-not-selector/) that said that Firefox implemented it in version 3 which was surprising considering it's not in CSS3 spec. – Jamie Barker Jun 12 '15 at 10:49
  • @Jamie Barker: Yep, I mention the same article in my link. It's either due to a bug or a misinterpretation of the spec but it was fixed soon after. – BoltClock Jun 12 '15 at 10:50
  • Fair enough. I don't understand why they decided to not add it, it seems like a perfectly sensible statement... One for the future, hopefully. – Jamie Barker Jun 12 '15 at 10:56
  • 1
    @Jamie Barker: I'm not sure why they made it so restrictive either, but you'll be happy to know that they're lifting the restriction in [Selectors 4](http://dev.w3.org/csswg/selectors-4/#negation). – BoltClock Jun 12 '15 at 10:58