W3docs

CSS :not() Pseudo Class

The :not() CSS pseudo-class selects and styles the elements that do not match a list of selectors. Read more about the pseudo-class and try examples.

The CSS :not() pseudo-class selects every element that does not match the selector you pass to it. Because it inverts a match, it is also called the negation pseudo-class.

This page explains what :not() does, when to reach for it, how it affects specificity, and the gotchas that trip people up — with runnable examples you can edit.

What :not() is

:not() is a functional pseudo-class: it takes a selector as an argument and matches any element that the argument does not select. Supported arguments include:

  • Type selector (e.g., p, span)
  • Class selector (e.g., .element)
  • ID selector (e.g., #header)
  • Pseudo-class selector (e.g., :last-child, :first-of-type)
  • Attribute selector (e.g., [type="text"])
  • The universal selector (*)

In Selectors Level 3 the argument had to be a single simple selector. Selectors Level 4 expanded it to accept a comma-separated list and compound or complex selectors, so you can write :not(.a, .b) or :not(ul li.first) in modern browsers.

When to use it

Reach for :not() when it is shorter to describe what you want to exclude than to list everything you want to include:

  • Style every list item except the last one: li:not(:last-child).
  • Style every link that is not external: a:not([target="_blank"]).
  • Add spacing between siblings without a trailing margin: .item:not(:first-child) { margin-top: 1rem; }.
  • Disable styling for one variant: .btn:not(.btn-ghost) { background: #8ebf42; }.

Important Notes

  • The :not() selector works with pseudo-classes, but does not support pseudo-elements.
  • The :not() keyword itself adds no specificity — only its argument does. So :not(.foo) has the same specificity as .foo (0, 1, 0), and a bare :not(p) weighs the same as p (0, 0, 1). This makes :not() cheaper than the equivalent extra class and can surprise you in override battles.
  • :not(.foo) matches anything that isn't .foo, including <html> and <body>. Always pair it with a context such as ul li:not(.foo) so it does not leak onto the whole document.
  • The :not() selector applies to every element that fails to match the argument, not just a single element.
  • An empty :not():not() with nothing inside — is invalid and the whole rule is ignored.

Version

Selectors Level 3

Selectors Level 4

Syntax

CSS :not() syntax

selector:not(argument) {
  css declarations;
}

Example of the :not() pseudo-class:

CSS :not() code example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      p {
        color: #666;
      }
      :not(p) {
        color: #8ebf42;
      }
    </style>
  </head>
  <body>
    <h2>:not() selector example</h2>
    <p>Lorem Ipsum is simply dummy text</p>
    <p>Lorem Ipsum is simply dummy text</p>
    <div>Lorem Ipsum is simply dummy text</div>
    <a href="https://www.w3docs.com" target="_blank">Link to W3docs</a>
  </body>
</html>

In the following example, there is an unordered list with a single class on the <li> tag.

Example of the :not() pseudo-class with the <li> tag:

CSS :not() another code example

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .text-blue {
        color: blue;
      }
      ul li:not(.text-blue) {
        color: #8ebf42;
      }
    </style>
  </head>
  <body>
    <h2>:not() selector example</h2>
    <ul>
      <li>List item 1</li>
      <li class="text-blue">List item 2</li>
      <li>List item 3</li>
    </ul>
  </body>
</html>

Passing a list of selectors (Selectors Level 4)

Modern browsers let you exclude several selectors at once by separating them with commas inside a single :not(). The rule below colors every list item except the muted and the active one:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      li {
        color: #8ebf42;
      }
      li:not(.muted, .active) {
        font-weight: bold;
      }
    </style>
  </head>
  <body>
    <h2>:not() with a selector list</h2>
    <ul>
      <li>Highlighted item</li>
      <li class="muted">Muted item</li>
      <li class="active">Active item</li>
      <li>Highlighted item</li>
    </ul>
  </body>
</html>

This is equivalent to the older, more verbose li:not(.muted):not(.active), which you can use if you need to support very old browsers.

Practice

Practice
What does the :not() pseudo-class in CSS do?
What does the :not() pseudo-class in CSS do?
Was this page helpful?