CSS the :not() selector

CSS the :not() selector

Intro

In my previous post I wrote a bit about the :not() selector and I got a lot feedback that people never heard of this element. So I figured I would dedicate a post just to the :not() CSS selector.

What is the :not() selector in CSS?

The :not() is a CSS pseudo-class that targets elements that do not match the selector given. Since it prevents specific items from being selected, it is known as the negation pseudo-class.

In essence you can target anything except what you put in the :not() selector.

:not() rules

There are a couple of rules when using the :not() selector. You should keep this in mind when using the :not() selector in your projects, cause they could cause unsual outcomes that have you burn hours trying to figure them out.

  • You cannot nest the :not() pseudo-class, which means you cannot do :not(:not(...))
  • You cannot use it with pseudo-elements such as ::before and ::after. It will work with :first-child and :last-child since they are simple selectors.
  • Using the :not() selector can increase the specificity of a rule. #foo:not(#bar) will match the same element as the simpler #foo but with a higher specificity.
  • Using just :not(.class) will match anything that isn't .class including <html> and <body>.
  • The :not() selector only applies to one element; you cannot use it to exclude all ancestors. body :not(table) a will still apply to links inside of a table, since <tr> will amtch with the :not()

How to use the :not() selector with multiple classes

It is possible to use the :not() selector with multiple classes.

Normally you would just want to do:

p:not(.foo) {

}

But maybe you want to avoid multiple classes? There are no real combinators with :not() and you cannot nest them. But you can chain them, which works similar to and.

p:not(.foo):not(.bar):not(.bold):not(.italic) {

}

Tricks with :first-child, :last-child and :nth-child()

I use the :not() CSS selector most often with the :first-child or :last-child pseudo-class.

Think of having a list that you want to add some spacing to, but you don't want to last item to also have spacing at the bottom right? Well with :not() that is super easy to solve!

li:not(:last-child) {
  margin-bottom: 20px;
}

This CSS will be applied to all <li> elements except the last child.

You could also do the reverse with :first-child

li:not(:first-child) {
  margin-top: 20px;
}

Or use it with :nth-child()

li:not(:nth-child(2)) {
  margin: 20px 0;
}

Conclusion

A lot of handy things can be achieved by using the :not() CSS selector. I know I use it a lot of times, for menus, list items and what not. Even flexbox grids!

I hope you learned something from this post, and hopefully you can enhance your CSS skills with this knowledge.

Let me know how you apply the :not() selector, I'm always eager to new learn tricks with it.

Did you find this article valuable?

Support Kars van Iersel by becoming a sponsor. Any amount is appreciated!