:not()
Selects elements that match neither the given selector nor any selector in the list.
Example
#.btn:not(:disabled):hover {
background: #6d28d9;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}<style>.btn { padding: 8px 14px; border: 0; border-radius: 8px; background: #7c3aed; color: #fff; font: inherit; cursor: pointer; }</style>
<div style="display: flex; gap: 8px;">
<button class="btn" type="button">Enabled</button>
<button class="btn" type="button" disabled>Disabled</button>
</div>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
#:not( <selector list> )Arguments
#- Every item without the class
done, including the one withlocked. - A list in the parentheses: neither
donenorlocked. Two plain items are left. - Every item except the first.
- Items that have no
classattribute at all.
Arguments in practice
#.done
done, including the one with locked.li:not(.done) { background: #7c3aed; color: #fff; }.done, .locked
done nor locked. Two plain items are left.li:not(.done, .locked) { background: #7c3aed; color: #fff; }:first-child
li:not(:first-child) { background: #7c3aed; color: #fff; }[class]
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 hitshtml,body, and other elements.
Related entries
#- :is()Matches an element against any selector in a list. Shortens long, repetitive selectors into a single notation.
- :where()Works like :is(), but always has zero specificity. Ideal for base styles that should be easy to override.
- :has()Selects an element based on what it contains or what follows it. Lets you style a parent according to its children.
- SpecificityA selector’s weight, which decides which rule wins when several rules set the same property on the same element.
- :first-childMatches an element that is the first child of its parent.
- A, BA comma combines several selectors into a single rule, to give them the same styles without repeating declarations.
Spotted a mistake or missing an example? Write to us.