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?

Top comments (7)

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 :)

Collapse
 
jwp profile image
John Peters

SASS is just cool indeed