Can I write a CSS selector selecting elements NOT having a certain class or attribute?
Yes. You can use the :not()
pseudo-class to exclude elements that have a certain class or attribute. For example:
- Select all
<div>
elements not having the classfeatured
:div:not(.featured) { /* styles here */ }
- Select all
<input>
elements not having atype
attribute:input:not([type]) { /* styles here */ }
- Combine multiple exclusions (logical AND) by chaining
:not()
:/* Select all divs that have NEITHER .hidden class NOR data-* attribute */ div:not(.hidden):not([data-info]) { /* styles here */ }
Below is more detail on how :not()
works, plus some caveats about combining exclusions and logical constraints in CSS.
1. Using :not()
to Exclude a Class
You can negate a single selector with :not(...)
. A common use is to style all elements of a certain kind except those with a specific class:
span:not(.highlight) { color: black; }
This applies color: black;
to every <span>
except those with class highlight
.
2. Excluding Elements That Have an Attribute
Similarly, if you want to target elements missing a certain attribute, you can do:
img:not([alt]) { border: 2px solid red; }
All <img>
elements without an alt
attribute get a red border.
3. Chaining Multiple :not()
Selectors
If you chain multiple :not()
, the logic is AND. For instance:
/* This means "Select <li> elements that do NOT have .active AND do NOT have data-x attribute" */ li:not(.active):not([data-x]) { opacity: 0.5; }
So the element must fail all conditions to be selected (i.e., have none of those classes/attributes).
No Direct “OR” in CSS Selectors
CSS doesn’t offer a straightforward “OR” operator in selectors. If you try something like :not(.foo, [bar])
, it won’t do what you might expect. You’d need separate selectors or more elaborate structures if you want an OR logic.
4. Caveats & Tips
-
Combining Many
:not()
Overusing or nesting multiple:not()
calls can become confusing. Keep your selectors readable. -
Edge Cases
- Remember that
:not()
only negates simple selectors in older CSS specs. Modern CSS (Selectors Level 4) allows more complex arguments inside:not(...)
, but check browser support. - If you need more advanced logic (like “select an element unless it has a child with class X”), you might look into the
:has()
pseudo-class. However,:has()
is still gaining full cross-browser support.
- Remember that
-
Performance
Typically not a big concern for a handful of:not()
selectors, but extremely complex or deep negations can impact rendering performance in large documents.
5. Summary
- Use
:not(.class)
to exclude elements that match a class. - Use
:not([attr])
to exclude elements with a certain attribute. - Chain multiple
:not()
for an AND logic (exclude multiple conditions). - CSS doesn’t provide a direct OR logic in selectors.
- For advanced or dynamic negation, consider newer features like
:has()
(with limited support) or handle logic differently (e.g., adding classes with JavaScript).
Key Takeaway
Yes, you can select elements not having a class or attribute by using the :not()
pseudo-class. Just remember that each :not()
excludes one simple selector, and combining multiple :not()
is an AND operation.