Css not child element
DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
The :not() property in CSS is a negation pseudo class and accepts a simple selector or a selector list as an argument. It matches an element that is not represented by the argument. The passed argument may not contain additional selectors or any pseudo-element selectors. The ability to use a list of selectors as an argument is considered experimental, although its supported is growing at the time of this writing, including Safari (since 2015), Firefox (since December 2020), and Chrome (since January 2021).
/* the X argument can be replaced with any simple selectors */ :not(X)
/* Style everything but the .different class */ li:not(.different)
However, if we use a pseudo-element selector as our argument it will not produce the expected result.
/* select alls that are not descendants of */ p:not(article *)
h2:not(:where(article *, section *)) < . >/* No match!
No Match!
*/
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.
The :not() pseudo class has been updated in the CSS Selectors Level 4 specification to allow an argument list. In CSS Selectors Level 3, it was only capable of accepting a single simple selector. As a result, browser support is a little divided between the Level 3 and Level 4 drafts.
IE | Edge | Firefox | Chrome | Safari | Opera |
---|---|---|---|---|---|
9+ | All | All | All | 12.1+ | All |
Android Chrome | Android Firefox | Android Browser | iOS Safari | Opera Mobile |
---|---|---|---|---|
All | All | All | All | All |
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Mobile / Tablet
Related
:is
:where
Psst! Create a DigitalOcean account and get $200 in free credit for cloud-based hosting and services.
Comments
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
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.
This should be bold.
This should not be bold.
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,
You don’t NOT want the paragraph with that class, but you do want the paragraph with the class no-style
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.
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
.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
Damn… this :not pseudo element was made backwards… this… li::before
li::before:not(.menu-item) is the same as… li::before
li.menu-item::before i thought this element was well made… an example below: li::before, li::before:not(.menu-item)
This rule: li::before, li::before:not(.menu-item) 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)
Thanks for your help, i appreciate that 🙂 but like i said,
li::before:not(.menu-item) (is the same as)
li::before(.menu-item) (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!
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. 🙂
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.
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:
[class*="icon-"]:not(.icon-wrapper) < line-height: 1; >.menu ul > li a < line-height: 50px; //overwritten by the ruleset above >
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.
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.
a[href$=".jpg"], a[href$=".gif"], a[href$=".png"] < /*css styles here*/ >
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
That’s what’s reflected in the content as well. It’s not that the specificity is unchanged, but the specificity is determined by the highest specificity in its argument.
/* chained :not is valid */ div:not(.someClass):not(anotherClass)
/* comma separated :not selectors are not valid */ div:not(.someClass), div:not(anotherClass)
I was not aware that comma separated :not selectors are invalid. This should be added to the Specificity section of the article.
It is valid CSS. This has tripped me up before also, but you have to think like CSS does and read it as :not(.someClass) which technically allows .anotherClass , and then further along reads :not(.anotherClass) which allows .someClass . By combining it in one line you are saying “not .someClass AND not .anotherClass”, not one OR the other (which basically cancels each other out).
One point that I rarely see brought up as for :not() ‘s usefulness is that you can keep the original styles of the element that you may not know the value of ahead of time. This comes in handy when you are applying utility classes to elements that could be of any display type. Basically, instead of this…
.show-children-on-hover * < display: none; >.show-children-on-hover:hover * < display: block; /* We just assumed every child element of .show-child-on-hover is of block display; chances are they are not. */ >
…we can instead hide the element when the parent is NOT hovered, and whenever it is, the rule below becomes invalid and the element it is attached to takes on its normal display value. Now your table won’t have display:block set to it like in the above example. I used display:block in this example because that seems to be the most common property when showing/hiding an element ( none and block ).
.show-children-on-hover:not(:hover) * < display: none; /* Only changes display when .show-children-on-hover is NOT hovered */ >
CSS the :not() selector
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. Lets look at a quick example:
:not() rules
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:
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; >
You could also do the reverse with :first-child
li:not(:first-child) margin-top: 20px; >
li:not(:nth-child(2)) margin: 20px 0; >
Here is a quick codepen sample to see it in action:
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.