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>
Browser Result
  • 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.

Summary

The CSS :not() pseudo-class selects elements that do not match the selector or selector list inside its parentheses. It can exclude classes, attributes, structural states, and other selectors while allowing the remaining elements to receive a CSS rule.

With :not(), you have reached the end of the CSS Pseudo-Classes section.