DEV Community

Cover image for The Powerful CSS not Selector
Braydon Coyer
Braydon Coyer

Posted on • Originally published at braydoncoyer.dev

The Powerful CSS not Selector

This article was originally posted on my personal blog.

The :not() CSS selector is a powerful addition to the pseudo-class toolbelt, allowing you to select elements that are omitted by its argument.

A basic :not() CSS Selector Example

Here’s an example. I have a few classes set up - one applies base styles for all buttons, one sets the styles of a primary button, and another determines what a primary disabled button should look like.

📢 I’m using SCSS in the example below to gain the benefit of class nesting and variables, but the application of the :not() selector is the same.

.button {
  border: none;
  padding: 1rem 2rem;
  border-radius: 0.5rem;
  cursor: pointer;
    margin-top: 1rem;
}

.button--primary {
  background: $button--primary;
  color: white;
}

.button--disabled {
  background: $button--disabled;
  cursor: auto;
}
Enter fullscreen mode Exit fullscreen mode

In order to align with accessibility, it’s important that the background of the button changes when in hover state. That’s simple enough; here’s the change.

.button--primary:hover {
  background: $button-primary-hover;
}
Enter fullscreen mode Exit fullscreen mode

But, after adding the :hover selector, we run into a problem. Try hovering over the disabled button and notice that the background changes as if we were hovering over an active primary button.

How do we get around this? The :not() selector makes this an easy fix, allowing the change to only affect primary buttons that are not disabled!

.button--primary:hover:not(.button--disabled) {
  background: $button-primary-hover;
}
Enter fullscreen mode Exit fullscreen mode

📢 Instead of using a class to determine if the button is disabled, I could have opted to use the :disabled attribute. I think the examples above are a bit easier to follow.

Browser Compatibility for the :not Selector

Thankfully, the :not() selector is supported by most major browsers.

Check out caniuse.com to see the exceptions.

Conclusion

In this article, we briefly discussed the :not() selector and saw a real-world example. A variety of options open up when using this selector - what applications can you think of?

Latest comments (7)

Collapse
 
jwp profile image
John Peters

SASS is just cool indeed

Collapse
 
qm3ster profile image
Mihail Malo

You have to admit that

.button {
  border: none;
  padding: 1rem 2rem;
  border-radius: 0.5rem;
  margin-top: 1rem;
  &:hover {
    cursor: pointer;
  }
  &:disabled {
    cursor: not-allowed;
  }
}

.button--primary {
  background: $button--primary;
  color: white;
  &:hover {
    background: $button-primary-hover;
  }
  &:disabled {
    background: $button-primary-disabled;
  }
}
Enter fullscreen mode Exit fullscreen mode

which just applies the :disabled because it comes later at same specificity is nicer.

Collapse
 
christiankozalla profile image
Christian Kozalla

Agree 100% - in addition, the above code uses nesting and Sass &
Good job 👍

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Prompted by your comment, I wanted a reminder of what SCSS vs Sass syntax looks like, and the current example is literally a button with hover 😂🤣

Thread Thread
 
christiankozalla profile image
Christian Kozalla

Uh, I didn't really mean Sass.. I use "Sass" and "SCSS" interchangeably. Although I know it isn't :D

Thread Thread
 
qm3ster profile image
Mihail Malo

I gathered 😂

Collapse
 
braydoncoyer profile image
Braydon Coyer

Yep, absolutely. But as I mentioned in the article, I chose to forgo the disabled property to show a specific use-case for the selector. The nesting is also a plus with SCSS, but I opted against it to allow others to follow a little easier.

Love the suggestion, though :)