Question
I want to write a CSS selector that matches all elements that do not have a specific class. For example, with 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 a selector that targets 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?
Also, in the real HTML I am working with, 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 use the CSS :not() pseudo-class to select elements that do not have a certain class or attribute. You will also learn the limits of this approach, how it behaves with descendant elements, and how to apply it safely in real stylesheets.
Concept
CSS includes a pseudo-class called :not() that lets you match elements that do not meet a condition.
For this question, the key idea is:
:not(.printable)
This selector matches any element that does not have the class printable.
You can also use :not() with attributes, such as:
:not([disabled])
which matches elements that do not have the disabled attribute.
Why this matters
In real projects, you often need to:
- style everything except a special group
- hide non-printable parts of a page during printing
- exclude buttons, ads, menus, or helper UI from certain layouts
- target elements that are missing an attribute or class
The :not() selector is useful because it lets you express exclusion directly in CSS instead of adding extra classes everywhere.
Important detail
*:not(.printable) means:
- select every element
- except elements that themselves have class
Mental Model
Think of :not() like a filter at a doorway.
- Every element walks toward the doorway.
- The filter checks one rule.
- If the element matches the excluded rule, it is blocked.
- If it does not match the excluded rule, it gets through.
For example:
*:not(.printable)
is like saying:
"Let in every element except those wearing the
printablebadge."
An element is judged by its own badge, not by its parent’s badge.
Syntax and Examples
The basic syntax is:
selector:not(condition)
Exclude a class
*:not(.printable) {
color: gray;
}
This matches every element that does not have class printable.
Exclude an attribute
input:not([disabled]) {
border: 1px solid green;
}
This styles only input elements that are not disabled.
Practical example for printing
@media print {
*:not(.printable) {
display: none;
}
}
This hides all elements that do not have the printable class.
More specific version
Sometimes you only want to target certain elements:
*() {
: ;
}
Step by Step Execution
Consider this HTML:
<div class="printable">Report</div>
<nav>Menu</nav>
<a href="#">Print</a>
<p class="printable">Important text</p>
And this CSS:
*:not(.printable) {
background: yellow;
}
Step-by-step
- CSS starts checking each element in the document.
- For
<div class="printable">, the element has classprintable.:not(.printable)fails.- The rule does not apply.
- For
<nav>, the element does not have classprintable.
Real World Use Cases
Here are common situations where :not() is useful:
Print styles
Hide navigation, buttons, and controls when printing:
@media print {
.page *:not(.printable) {
display: none;
}
}
Form styling
Style all inputs except disabled ones:
input:not([disabled]) {
background: white;
}
Navigation and UI exclusions
Apply spacing to all list items except the last one:
li:not(:last-child) {
margin-bottom: 8px;
}
Content theming
Style all cards except featured cards differently:
.card:not(.featured) {
opacity: 0.8;
}
Data tables
Real Codebase Usage
In real codebases, developers often use :not() in a few practical patterns.
1. Excluding special cases
Instead of creating many extra classes, developers often write one general rule and exclude special elements:
.button:not(.button-secondary) {
background: blue;
color: white;
}
2. Guarding styles
A rule can apply broadly while protecting elements that should behave differently:
input:not([type="checkbox"]):not([type="radio"]) {
width: 100%;
}
3. Print and export layouts
Pages often contain controls that should not appear in output:
@media print {
.toolbar,
.sidebar,
.actions {
display: none;
}
}
Sometimes this is clearer than trying to hide everything with :not().
Common Mistakes
Mistake 1: Thinking :not(.printable) excludes children of .printable
Broken assumption:
<div class="printable">
<span>Text</span>
</div>
*:not(.printable) {
color: red;
}
Many beginners expect the span not to match. But it does match, because the span itself does not have class printable.
How to avoid this:
- remember that CSS matches each element individually
- if needed, write a more specific structure-based selector
Mistake 2: Using :not() too broadly
*:not(.printable) {
display: none;
}
This can affect many more elements than expected, including layout wrappers and nested content.
Comparisons
| Selector | Meaning | Example Match | Common Use |
|---|---|---|---|
.printable | Elements with class printable | <p class="printable"> | Include a special group |
:not(.printable) | Elements without class printable | <nav> | Exclude a special group |
[class] | Elements that have any class attribute | <div class="box"> | Match elements with classes |
:not([class]) | Elements with no class attribute |
Cheat Sheet
Core syntax
:not(selector)
Common examples
:not(.printable)
input:not([disabled])
li:not(:last-child)
button:not(.secondary)
Match elements without a class
*:not(.printable)
Match elements without an attribute
input:not([disabled])
Important rule
:not() checks the current element, not its parent or children.
Useful reminders
.printable= has classprintable:not(.printable)= does not have class
FAQ
Can CSS select elements that do not have a certain class?
Yes. Use the :not() pseudo-class:
:not(.printable)
How do I select all elements without the printable class?
Use:
*:not(.printable)
This matches every element that does not have that class.
Does :not(.printable) exclude children inside a .printable element?
No. It only checks the element being matched. A child inside .printable still matches if the child itself does not have the class.
Can I use :not() with attributes?
Yes. For example:
input:not([disabled])
This matches inputs that are not disabled.
Is *:not(.printable) a good idea for print CSS?
Sometimes, but it can be too broad. If you know which elements should be hidden, explicit selectors like are often easier to maintain.
Mini Project
Description
Build a simple print-friendly article page. The page contains content that should be printable and interface elements that should stay on screen only. This project demonstrates how to use :not() and how to decide when explicit selectors may be clearer than broad exclusion rules.
Goal
Create a small page where printable content remains visible in print mode while navigation and action links are hidden.
Requirements
- Create an HTML page with a heading, article text, a navigation block, and a print link.
- Add the class
printableto the content that should remain visible for printing. - Write CSS that visually distinguishes printable and non-printable parts on screen.
- Add a print stylesheet using
@media print. - Ensure the navigation and print link do not appear when printing.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.
CSS Parent Selector Explained: Selecting a Parent <li> from an <a>
Learn whether CSS has a parent selector, how :has() works, and practical alternatives for styling a parent li from a child anchor.