I discovered the CSS :not selector recently, and it’s pretty cool. In a nutshell, you can chain it or apply it to certain selectors and style everything that does NOT meet the condition (e.g. everything BUT span tags). Let’s get a bit more formal.

Definition Of The :not Selector

According to the MDN:

The negation CSS pseudo-class, :not(X), is a functional notation taking a simple selector X as an argument. It matches an element that is not represented by the argument. X must not contain another negation selector, or any pseudo-elements.

The specificity of the :not pseudo-class is the specificity of its argument. The :not pseudo-class does not add to the selector specificity, unlike other pseudo-classes. Pretty handy, right? Let’s look at some examples.

Example 1 – Not A Selector

This case of :not will negate all selectors specified. Our HTML might look like this:

<section>
  <p>Pellentesque habitant morbi tristique senectus et netus et.</p>
  <span>Malesuada fames ac turpis egestas. Vestibulum tortor quam.</span>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit!</p>
</section>

and our CSS like this:

section :not(p) {
  color: rgb(40,170,220);
}

and our output like this:

Example 2 – Not A Class

This case of :not will negate all classes specified. In other words, we’ll target everything except the class in question. Our HTML may look like this:

<section class="highlight">
  <p>Pellentesque habitant morbi...</p>
</section>
<section>
  <p>Lorem ipsum dolor....</p>
</section>

and our CSS like this:

body {
  background-color: rgb(40,170,220);
  color: #fff;
}
section {
  padding: 20px;
  text-align: center;
}
section:not(.highlight) {
  background-color: rgb(80,80,80);
  font-size: 14px;
}

and the output like this:

Example 3 – Usage With Pseudo Selectors

The spec mentions we can’t combine the :not selector with pseudo elements. We can, however, combine it with pseudo selectors, for example :nth-child. Here’s an example of what some HTML might look like:

<body>
  <p>Pellentesque habitant morbi...</p>
  <p>Pellentesque habitant morbi...</p>
  <p>Pellentesque habitant morbi...</p>
</body>

and our CSS like this:

body {
  background-color: rgb(40,40,40);
  color: #fff;
}
p:not(:nth-child(1)) {
  color: rgb(255,50,100);
}

and our output like this:

Wrong Uses

As mentioned before, we can’t combine the CSS :not selector with pseudo elements, for example ::before, ::after, and ::first-line. It fails to work in this instance. For a list of pseudo elements, check out the MDN reference.

Support

Support for the :not selector is actually fairly good overall. All Chrome & Firefox supports it, Safari 3.2 and up support it, and IE9 and up also. I would still recommend keeping the usage case of this selector to purely aesthetic so that old IE falls back nicely…progressive enhancement if you must.

Wrap Up

This could’ve easily been added to my list of under the radar CSS selectors had I discovered it before. It’s a cool selector, and with a little thought, there are many useful cases where it can be applied. And that’s a wrap! Have you used this selector before? What are your thoughts about it? Leave any comments, questions, or feedback below, and thanks for reading.