:not(s)

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;
}

Visual representation of the varied uses of :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

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.

Comments

  1. User Avatar
    mesamorpho
    Permalink to comment#

    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.

  2. User Avatar
    razvan
    Permalink to comment#

    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 ?

  3. User Avatar
    Pratip Ghosh
    Permalink to comment#

    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,

    • User Avatar
      alpipego
      Permalink to comment#

      @Pratip: simply use straight forward css:

      p {
          font-weight: bold;
      }
      .no-style {
          font-weight: normal;
      }
      

      You don’t NOT want the paragraph with that class, but you do want the paragraph with the class no-style

    • User Avatar
      Tiffany Stoik
      Permalink to comment#

      A million years later, but you could just do

      p:not(.no-style) { font-weight: bold }

  4. User Avatar
    Jimba Tamang

    it’s amazing, I’ve no idea how many times I am going to use it.

  5. User Avatar
    K. Alan Bates
    Permalink to comment#

    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…

    [class *= "foo"] not([class *= "bar"]){
       /*This element is guaranteed to be foo and guaranteed to not be bar */
       content: "Do stuff";
    }
    

    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.

  6. User Avatar
    David Puerto
    Permalink to comment#

    .foo:not([class*=bar]){}; can be used/ful too!

  7. User Avatar
    James Holby
    Permalink to comment#

    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

  8. User Avatar
    Lucas Martins
    Permalink to comment#

    I am using

    .foo:not(.bar, .baz, .qux)
    
  9. User Avatar
    cridavcor
    Permalink to comment#

    Use your example in simple search blog not DB.

    Please forgive my english language.

  10. User Avatar
    Luis Trinidad
    Permalink to comment#

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

    • User Avatar
      Joe
      Permalink to comment#

      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:”●”}

  11. User Avatar
    Luis Trinidad
    Permalink to comment#

    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…

  12. User Avatar
    Kick
    Permalink to comment#

    Hi How Are you .
    I am fine thanks .

    by by

  13. User Avatar
    Corry Frydlewicz

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

  14. User Avatar
    Paceaux
    Permalink to comment#

    Something I think is missed here is

    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:

         <section class="menu">
        <ul>
        <li>
        <a href="/" class="icon-logo">
    
        [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.

  15. User Avatar
    Ryan
    Permalink to comment#

    I’m using code that adds an icon to links that are external.

    <style>
    
    #block-system-main a[href^="http"], #block-system-main a[href^="https"] {
        background-image: url("/sites/default/files/external.png");
        background-repeat: no-repeat;
        background-position: right center;
        padding-right: 20px;
    }
    </style>
    

    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 >

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-closeicon-emailicon-linkicon-logo-staricon-menuicon-searchicon-staricon-tag