The :not(X)
property in CSS is a negation pseudo class and accepts a simple selector1 as an argument. Essentially, just another selector of any kind.
:not
matches an element that is not represented by the argument. The passed argument may not contain additional selectors or any pseudo-element selectors.
See the Pen :not(X) by GRAY GHOST (@grayghostvisuals) on CodePen.
/* the X argument can be replaced with any simple selectors */:not(X) { property: value;}
In this example we have an unordered list with a single class on the li
:
<ul> <li></li> <li class="different"></li> <li></li></ul>
Our CSS would select all the <li>
elements except the one(s) with a class of .different
.
/* Style everything but the .different class */li:not(.different) { font-size: 3em;}
You could also do the same using pseudo classes which are considered a simple selector.
p:not(:nth-child(2n+1)) { font-size: 3em;}
However if we use a pseudo element selector as our argument it will not produce the expected result.
:not(::first-line) { /* ::first-line is a pseudo element selector and not a simple selector */ color: white;}
![](/static/ka8II/static/picture/not-slide.jpg?d=c1964b2c5&m=ka8II)
:not()
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.
Negations may not be nested so :not(:not(...))
is never permitted. Authors should also note that since pseudo elements are not considered a simple selector, they are not valid as an argument to :not(X)
. Be mindful when using attribute selectors as some are not widely supported as others. Chaining :not
selectors with other :not
selectors is permissible.
Other Resources
- W3C Selectors Spec
- W3C CSS Working Group Selectors 3
- MDN Docs
- W3C Simple Selectors Definition
- Caniuse.com
Browser Support
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
14+ | 4.0+ | 3+ | 11.1+ | 9+ | 2.1+ | 3.0+ |
1 A simple selector is classified as a Type Selector, Universal Selector, Attribute Selector, Class Selector, ID Selector, or Pseudo Class Selector.
Thanks for covering the :not() selector, and as always with useful examples!
I would like to point out though, that the example depicted in the image of
p:not(:nth-child(2n+1))
is somewhat ambiguous and may be misleading, at least without explicit reference. The example holds true when looking at your demo page, where the first child of the<div class="f">
block is a<header>
element but anyone not looking at the demo page is likely going to expect that the second and fourth elements are selected/displayed with a white background — since the example selector really says: select any<p>
element that is not an odd child, whereas the image shows exactly the two odd elements as being selected.On the image “Visual representation of the varied uses of :not()” shouldn’t you point the 2 and 4 boxes ?
2n+1 is an odd number.So when you say :not(odd) should result in targeting the even numbers.
Am I wrong ?
Thanks for the wonderful article. However, I would like to know whether there is a way to identify a single element in my html page that would “not” take the general styling/css? What “not” does is specify all other element and “not” the one in the argument. I just want the opposite.
<style>
.div-class p{font-weight: bold;}
.div-class p:not(.no-style){font-weight: normal;}
</style>
<div class="div-class">
<p>This should be bold.</p>
<p class="no-style">This should not be bold.</p>
</div>
I would like the “p” with the “no-style” class to have a normal font weight. It’s currently the opposite. I hope to have made myself clear.
Thanks,
@Pratip: simply use straight forward css:
You don’t NOT want the paragraph with that class, but you do want the paragraph with the class no-style
A million years later, but you could just do
p:not(.no-style) { font-weight: bold }
it’s amazing, I’ve no idea how many times I am going to use it.
Regarding class selectors being valid “simple selectors” for a not…
are regex class selectors considered “simple”?
Can I create a selector (with whatever particular, correct syntax) like so…
Note that I’m asking because this specified rule is not working (fails SASS 3.3 compilation)
With as hard as css has always sucked at specifying a (pretty basic) rules engine, I’m thinking not…but considered it worth the shot to ask.
.foo:not([class*=bar]){}; can be used/ful too!
Just wanted to point out that
:not
can indeed be chained per the spec:html|*:not(:link):not(:visited)
§6.6.7 http://www.w3.org/TR/css3-selectors/#negation
I am using
should it work?
Yes, it works.
.foo:not(.bar, .baz, .qux)
doesn’t work in CSS.
You’re probably using SCSS/SASS that converts it into
.foo:not(.bar):not(.baz):not(.qux)
And my biggest problem with that, is the specificity it gains each time you add a :not
You right, Bernard Skibinski!
Use your example in simple search blog not DB.
Please forgive my english language.
Damn… this :not pseudo element was made backwards…
this…
li::before{content:”●”}
li::before:not(.menu-item){content:none}
is the same as…
li::before{content:”●”}
li.menu-item::before{content:none}
i thought this element was well made… an example below:
li::before, li::before:not(.menu-item) {content:”●”}
this should be the way :not() must work!
that last example says… that every li element will have {content:”●”} except .menu-item..
but we still have the same as i can see… i have tried tons ways but havent being able to make it work… please advice me if im wrong :)
This rule:
li::before, li::before:not(.menu-item) {content:”●”}
Is saying “Every li AND Every li that isn’t .menu-item should have content ●”.
I think you want this:
li::before:not(.menu-item) {content:”●”}
Thanks for your help, i appreciate that :) but like i said,
li::before:not(.menu-item) {content:”●”} (is the same as)
li::before(.menu-item) {content:none} (and this one is shorter)
i wanted to do like you said first:
“Every li AND Every li that isn’t .menu-item should have content ●”
but is not working for me…
Check out the “wrong uses” section here: http://callmenick.com/post/the-css-not-selector
The :not() selector will not work on pseudo elements like :before. Try writing it like this instead:
that was a good one i didn’t tried i think…
but didn’t work either, thanks anyway :)
and nice and simple article btw!
Hi How Are you .
I am fine thanks .
by by
Another useful one (especially when setting up defaults that you expect to be overridden by classes) is :not([class]). It only styles the element if it has no classes assigned to it at all. :)
Something I think is missed here is
What I recently learned is that you can actually get burned by this matter of “argument specificity inheritance”:
.foo:not(#bar)
will have a specificity of 0,1,1,0. Understood another way, you have now given a class the specificity of an ID.
It’s not too likely that someone might do this. However, a use-case I just ran into today was:
You wouldn’t expect this result at all. At least I didn’t. But it happened, because
:not()
inherits specificity. So I had a ruleset with a specificity of 0,0,2,0 overwriting a ruleset with a specificity of 0,0,1, 3.Here’s some documented proof of this in action:
The moral of the story is, “the argument you pass into
:not()
should be less specific than what it’s chained to.I’m using code that adds an icon to links that are external.
My Question is:
how do i alter this code so any link that is surrounding an < img >, will NOT show the external icon?
IE: < a >< img >< /a >
@ ryan
You can use this. This equates to – any a tag with an href attribute that ends in “.jpg”, “.gif”, “.png” Just add or remove whatever image file types you need.
How to apply :not in following situation
This should be bold.
This should be bold.
This should be bold.
This should not be bold.
I would like to set same background color using .menu class but at the same time I also dont want to apply same color to hidden-menu class
Thanks,
I wonder why:
.container > *:not(.someclass:first-child){ background:red }
isn’t working, while ..
.container > *:not(:first-child){ background:red }
works.
Tried just in FF, but this should work, shouldn’t it?
Try container > *:not(.some class):not(:first-child), you should have better luck chaining nots rather than chaining selectors inside a not