Question
I want to write a CSS selector that matches elements that do not have a specific class. For example, given this HTML:
<html class="printable">
<body class="printable">
<h1 class="printable">Example</h1>
<nav>
<!-- Some menu links... -->
</nav>
<a href="javascript:void(0)" onclick="self.print()">Print me!</a>
<p class="printable">
This page is super interesting and you should print it!
</p>
</body>
</html>
I would like to write a CSS rule that selects all elements that do not have the printable class. In this example, that would match the nav and a elements.
Is this possible in CSS?
In the real HTML, there will be many more elements without the printable class than with it.
Short Answer
By the end of this page, you will understand how to exclude elements in CSS using the :not() pseudo-class. You will learn how to target elements that do not have a certain class or attribute, how selector specificity works in this situation, and how this pattern is used in real stylesheets such as print styles, component styling, and UI exclusions.
Concept
CSS can select elements not only by what they are, but also by what they are not. The main tool for this is the :not() pseudo-class.
If you want to match elements that do not have the class printable, you can use:
:not(.printable)
This means:
.targets a class.printablemeans “elements with the classprintable”:not(.printable)means “elements that do not have the classprintable”
This matters because real interfaces often need exclusion rules, such as:
- hide everything except printable content
- style all buttons except disabled ones
- target inputs that are not checked
- apply layout rules to items that are not marked special
You can also exclude attributes in the same way:
:not([disabled])
That matches elements that do not have a disabled attribute.
A key detail: does magically mean “every element on the page” unless your selector says so. It filters whatever selector it is attached to. For example:
Mental Model
Think of :not() like a filter on a guest list.
*means “everyone is invited”.printablemeans “people wearing a printable badge”*:not(.printable)means “everyone except people wearing that badge”
So :not() does not create a list by itself. It removes items from a list you already selected.
Another way to think about it:
- First choose the group
- Then remove the ones you do not want
That is exactly how CSS applies :not().
Syntax and Examples
The basic syntax is:
selector:not(condition)
Exclude a class
*:not(.printable) {
outline: 1px solid red;
}
This matches every element that does not have the printable class.
With your HTML:
<html class="printable">
<body class="printable">
<h1 class="printable">Example</h1>
<nav></nav>
<a href="#">Print me!</a>
<p class="printable">Text</p>
</body>
Step by Step Execution
Consider this CSS:
*:not(.printable) {
color: red;
}
And this HTML:
<div class="printable">A</div>
<div>B</div>
<p>C</p>
Here is what happens step by step:
-
*starts by matching all elements.div.printabledivp
-
:not(.printable)removes any element with theprintableclass.div.printableis removeddivstays
Real World Use Cases
Print styles
A very common use of :not() is in print stylesheets:
@media print {
.page *:not(.printable) {
visibility: hidden;
}
}
This can be used to suppress menus, ads, sidebars, or controls.
Forms
Style only fields that users can interact with:
input:not([disabled]),
select:not([disabled]),
textarea:not([disabled]) {
background: white;
}
Navigation and menus
Highlight links except the current page:
nav a:not(.active) {
opacity: 0.7;
}
Cards and lists
Add spacing to all items except featured ones:
Real Codebase Usage
In real projects, developers often use :not() as a small exclusion tool, not as the entire styling strategy.
Common patterns
Guard-style exclusions
Developers often apply a default style and exclude a special case:
.button:not(.button--secondary) {
background: royalblue;
color: white;
}
This is similar to a guard clause in programming: “apply this unless it is the special case.”
Form validation
input:not([type="checkbox"]):not([type="radio"]) {
width: 100%;
}
This is common when text-like inputs should share layout rules but checkboxes and radios should not.
Progressive enhancement
.js-enabled .menu-item:not(.is-open) .submenu {
display: none;
}
This avoids hiding currently open items.
Common Mistakes
1. Forgetting to define the base selector
Broken example:
:not(.printable) {
color: red;
}
This is valid CSS, but beginners often misunderstand it. It means “any element that is not .printable,” which may be much broader than intended.
If you only want certain elements, be explicit:
body *:not(.printable) {
color: red;
}
2. Hiding too much with display: none
Broken example:
@media print {
*:not(.printable) {
display: none;
}
}
This may hide container elements and cause printable children to disappear too.
Safer approaches include:
- targeting specific sections
- styling a wrapper element
- using a dedicated print layout
3. Confusing “does not have this class” with “is not inside this class”
These are different:
*()
Comparisons
| Selector | Meaning | Example | Best use |
|---|---|---|---|
.printable | Elements with the class | .printable | Target included items |
:not(.printable) | Elements without the class | *:not(.printable) | Exclude one class from a group |
[disabled] | Elements with an attribute | input[disabled] | Match by attribute presence |
:not([disabled]) | Elements without an attribute | input:not([disabled]) |
Cheat Sheet
/* Elements without a class */
*:not(.printable) {}
/* Specific element without a class */
div:not(.printable) {}
/* Elements without an attribute */
input:not([disabled]) {}
/* Multiple exclusions */
input:not([type="checkbox"]):not([type="radio"]) {}
/* Exclude an active item */
a:not(.active) {}
Rules to remember
:not()excludes matching elements- It filters the selector before it
*:not(.printable)means all elements except those withprintablediv:not(.printable)means onlydivelements without that class- You can exclude classes, attributes, element types, and more
- Be careful with
*because it is very broad - In print layouts, hiding everything except one class can fail if parent elements are hidden
FAQ
Can CSS select elements that do not have a class?
Yes. Use the :not() pseudo-class, such as *:not(.printable).
How do I select elements that do not have an attribute in CSS?
Use :not([attribute]). For example, input:not([disabled]) selects enabled inputs.
Is :not(.class) valid CSS?
Yes. It is a standard CSS pseudo-class and is widely used.
What is the difference between :not(.printable) and .printable *?
:not(.printable) checks whether the element itself lacks the class. .printable * selects elements inside an element with that class.
Why does *:not(.printable) sometimes hide more than expected in print CSS?
Because if a parent element is hidden, its children disappear too, even if a child would otherwise match your intended rule.
Should I use :not() or add a special class to the elements I want?
If the included elements are few and well-defined, adding a positive class or wrapper is often easier to maintain. Use :not() when the exclusion is simpler than the inclusion.
Mini Project
Description
Create a small print-friendly article page where some content should appear in print and some content should stay on screen only. This project demonstrates how to use :not() to exclude non-printable elements and why selector scope matters.
Goal
Build a page where article content is printable, while navigation and action links are excluded from print styling.
Requirements
- Create an HTML page with a heading, paragraph text, a navigation area, and a print link.
- Add a
printableclass to the content you want treated as printable. - Use
:not()in CSS to style or hide elements that are not printable. - Include a print media rule.
- Keep the example simple and fully working.
Keep learning
Related questions
Can HTML Checkboxes Be Readonly? Understanding readonly vs disabled in HTML Forms
Learn why HTML checkboxes do not support readonly, how disabled differs, and practical ways to prevent changes while still submitting values.
Can You Change `input type="date"` Format in HTML?
Learn how HTML date inputs format values, why you cannot force DD-MM-YYYY, and how to display custom date formats safely.
Can You Style Half a Character in CSS? Text Effects with CSS and JavaScript
Learn how to style half of a character using CSS and JavaScript, including overlay techniques for dynamic text effects.