CSS pseudo-classPseudo-classes

:not()

Selects elements that match neither the given selector nor any selector in the list.

On this page

Example

#
CSS
.btn:not(:disabled):hover {
  background: #6d28d9;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
Preview

Hover over both buttons. The disabled one doesn’t change color, because the hover rule excludes it.

Definition and usage

#

The :not() pseudo-class flips a condition around. li:not(.done) selects list items without the class done, and input:not([type="checkbox"]) every field except checkboxes. It lets you style "everything except" without writing a rule you’ll later have to undo.

Modern browsers accept a list of selectors in the parentheses, including compound ones: :not(.a, .b) means "neither .a nor .b", the same as :not(.a):not(.b). The list doesn’t forgive mistakes, though: one invalid selector invalidates the whole rule. Pseudo-elements also can’t appear inside the parentheses.

The specificity of :not() is the weight of the strongest selector in the list, not zero. So p:not(#intro) has a weight of (1, 0, 1). Also watch out for a bare :not(p): it matches everything that isn’t a paragraph, including html and body, so it’s worth narrowing it down, e.g. .menu > :not(.active).

Syntax

#
Syntax
:not( <selector list> )

Arguments

#
  • .done

    Every item without the class done, including the one with locked.
  • .done, .locked

    A list in the parentheses: neither done nor locked. Two plain items are left.
  • :first-child

    Every item except the first.
  • [class]

    Items that have no class attribute at all.

Arguments in practice

#

.done

Every item without the class done, including the one with locked.
li:not(.done) { background: #7c3aed; color: #fff; }

.done, .locked

A list in the parentheses: neither done nor locked. Two plain items are left.
li:not(.done, .locked) { background: #7c3aed; color: #fff; }

:first-child

Every item except the first.
li:not(:first-child) { background: #7c3aed; color: #fff; }

[class]

Items that have no class attribute at all.
li:not([class]) { background: #7c3aed; color: #fff; }

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • Instead of writing a rule for everything and then undoing it for one element, exclude that element with :not() right away. The code is shorter and doesn’t fight itself.
  • Watch the weight: :not(#id) adds the specificity of an ID, even though it doesn’t select anything by that ID.
  • Always use a bare :not() with context, e.g. .list > :not(.hidden). Without it, the rule also hits html, body, and other elements.

Related entries

#

Spotted a mistake or missing an example? Write to us.