CSS :not() Pseudo-Class
The CSS :not() pseudo-class selects elements that do not match a specified selector. It is useful when most elements in a group should receive a style but one or more elements need to be excluded.
The :not() Pseudo-Class
The :not() pseudo-class places the selector to exclude inside its parentheses.
p:not(.intro) {
color: #777777;
}
The selector p:not(.intro) matches <p> elements that do not have the intro class.
How :not() Works
The selector before :not() identifies the elements to consider, while the selector inside the parentheses identifies which of those elements should be excluded.
<p class="intro">Introduction paragraph.</p>
<p>Regular paragraph.</p>
<p>Another regular paragraph.</p>
p:not(.intro) {
color: #0088cc;
}
The two regular paragraphs match because they do not have the intro class. The first paragraph is excluded because it matches .intro.
Excluding a Class
One of the simplest uses of :not() is excluding elements that have a particular class.
li:not(.current) {
color: #777777;
}
li.current {
color: #0088cc;
font-weight: bold;
}
<ul>
<li>HTML</li>
<li class="current">CSS</li>
<li>JavaScript</li>
</ul>
- HTML
- CSS
- JavaScript
The first and third list items match li:not(.current). The second item is excluded because it has the current class.
Excluding an Attribute
The selector inside :not() can also be an attribute selector. This makes it possible to select elements that do not have a particular attribute or attribute value.
input:not([required]) {
background-color: #f5f5f5;
}
<input type="text" name="first-name" required>
<input type="text" name="middle-name">
The second input matches because it does not have the required attribute. The first input is excluded.
Using :not() with Structural Pseudo-Classes
The :not() pseudo-class can be combined with structural pseudo-classes. A common example is applying spacing or separators to every item except the last one.
li:not(:last-child) {
margin-bottom: 10px;
}
Every <li> except the last child receives the bottom margin. This is useful when spacing or a separator is needed between items but not after the final item.
li:not(:first-child) {
border-top: 1px solid #dddddd;
}
This selector applies a top border to every matching list item except the first child.
Excluding Multiple Selectors
The :not() pseudo-class can contain a selector list, allowing several selectors to be excluded at the same time.
p:not(.intro, .note) {
color: #777777;
}
<p class="intro">Introduction.</p>
<p>Regular paragraph.</p>
<p class="note">Important note.</p>
<p>Another regular paragraph.</p>
The regular paragraphs match, while paragraphs with either the intro or note class are excluded.
Keeping :not() Selectors Readable
The :not() pseudo-class can make selectors concise, but complicated exclusions can also make CSS harder to understand. For beginner CSS, it is usually best to keep the selector inside :not() simple and use it when the exclusion makes the rule easier to read.
.menu li:not(.current) {
color: #777777;
}
This selector clearly communicates that list items inside .menu should be styled unless they have the current class.
If a selector requires several complicated exclusions to explain which elements should match, using a class directly may produce CSS that is easier to maintain.
When to Use :not()
Use :not() when a group of elements should receive the same styles except for elements that match a particular selector. Common uses include excluding a class, excluding elements with an attribute, or leaving the first or last item out of a repeated style.
The pseudo-class is especially useful when the HTML already contains enough information to identify the exception and adding another class solely for CSS would be unnecessary.
