Question
How can I select all <input> elements except radio buttons and checkboxes with CSS? Does the :not() pseudo-class support multiple selectors?
.Copyform input:not([type="radio"], [type="checkbox"]) {
/* CSS rules here */
}
I have seen examples using multiple selectors inside :not(), but this selector does not appear to work as expected when filtering by the type attribute.
Short Answer
You will learn how CSS :not() excludes elements that match a selector, how modern :not() supports a comma-separated selector list, and how to write a broadly compatible selector for inputs other than radio buttons and checkboxes.
Concept
The CSS :not() pseudo-class is a negation selector: it matches an element only when that element does not match the selector inside the parentheses.
For example:
input:not([type="radio"])
This selects <input> elements whose type attribute is not radio.
Modern CSS allows :not() to receive a selector list, separated by commas:
input:not([type="radio"], [type="checkbox"])
This means: select an input that is neither [type="radio"] nor [type="checkbox"].
However, older browser implementations supported only one simple selector inside each :not(). For maximum compatibility, use two chained :not() pseudo-classes:
input:not([type="radio"]):not([type="checkbox"])
Both conditions must be true, so radio and checkbox inputs are excluded.
Also note that [type="radio"] checks the HTML attribute. An input without a type attribute is still a text input in HTML, and it will match this selector because it is not explicitly marked as radio or checkbox.
Mental Model
Think of :not() as a bouncer at a door.
inputmeans: allow all input elements into the line.:not([type="radio"])means: turn away anyone wearing aradiobadge.:not([type="checkbox"])means: also turn away anyone wearing acheckboxbadge.
Chaining the two rules means an input must pass both checks before it is selected.
Syntax and Examples
The basic syntax is:
selector:not(selector-to-exclude) {
property: value;
}
Exclude one input type
input:not([type="radio"]) {
outline: 2px solid steelblue;
}
This styles every input except radio buttons.
Exclude radio buttons and checkboxes (widely compatible)
.Copyform input:not([type="radio"]):not([type="checkbox"]) {
width: 100%;
padding: 0.5rem;
}
This is the safest form when supporting older browsers.
Modern selector-list form
.Copyform input:not([type="radio"], [type="checkbox"]) {
width: 100%;
padding: 0.5rem;
}
In modern browsers, this has the same result. The comma means or inside :not(): exclude inputs that are radio or checkbox.
If Copyform is a class name, it needs a leading dot:
.Copyform input { }
Without the dot, Copyform is interpreted as an HTML element named <copyform>.
Step by Step Execution
Consider this HTML:
<form class="Copyform">
<input type="text" placeholder="Name">
<input type="email" placeholder="Email">
<input type="radio" name="plan" value="basic">
<input type="checkbox" name="terms">
<input type="password" placeholder="Password">
</form>
And this CSS:
.Copyform input:not([type="radio"]):not([type="checkbox"]) {
border: 2px solid green;
}
The browser evaluates each input:
- The text input is not radio and not checkbox, so it matches.
- The email input is not radio and not checkbox, so it matches.
- The radio input fails
:not([type="radio"]), so it does not match. - The checkbox fails
:not([type="checkbox"]), so it does not match. - The password input is not radio and not checkbox, so it matches.
Only text, email, and password inputs receive the green border.
Real World Use Cases
input:not(...) is useful whenever a form contains controls that need different visual treatment.
- Form layouts: Make text-like fields full width while leaving small radio buttons and checkboxes at their natural size.
- Shared input styling: Apply padding, borders, and font settings to most inputs without breaking toggle controls.
- Checkout forms: Style name, address, email, and card fields while treating consent checkboxes separately.
- Settings pages: Apply consistent field styles but keep notification toggles, radios, and file pickers specialized.
- Design systems: Define a reusable base style for text-entry controls and create separate rules for choice controls.
Real Codebase Usage
In real projects, developers often avoid trying to style every possible <input> with one broad selector. Different input types have very different native behavior.
A common pattern is to style text-entry inputs explicitly:
.form-control,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
textarea,
select {
border: 1px solid #999;
border-radius: 4px;
padding: 0.5rem;
}
This approach is often clearer when a design system supports a known set of controls.
When a broad rule is appropriate, chained negation keeps exceptions readable:
.form input:not([type="radio"]):not([type="checkbox"]):not([type="file"]) {
min-height: 2.5rem;
}
Many codebases also use semantic classes to reduce dependence on input types:
<input class="form-field" type="email">
<input class="form-choice" type="checkbox">
.form-field { padding: 0.5rem; }
.form-choice { accent-color: rebeccapurple; }
Classes make component intent explicit and are easier to maintain when markup changes.
Common Mistakes
Forgetting the class prefix
/* Looks for a <Copyform> element, not class="Copyform" */
Copyform input { }
Use a dot for a class:
.Copyform input { }
Using a comma outside :not()
/* Incorrect: this styles all checkboxes in addition to the first selector */
input:not([type="radio"]), [type="checkbox"] {
padding: 0.5rem;
}
A comma outside parentheses creates separate selectors. Chain :not() instead:
input:not([type="radio"]):not([type="checkbox"]) {
padding: 0.5rem;
}
Expecting old browsers to support selector lists in :not()
input:not([type="radio"], [type="checkbox"]) { }
This is valid modern CSS, but older browser support may be a concern. Use chained :not() calls when compatibility matters.
Styling every non-radio/non-checkbox input as if it were a text field
The selector can also match inputs such as file, range, color, submit, and date. These controls often need separate styling. Either exclude additional types or list only the text-entry types your form uses.
Confusing missing attributes with missing input behavior
<input placeholder="Search">
This element behaves as type="text", but it does not literally have a type="text" attribute. It matches input:not([type="radio"]), but it does not match input[type="text"].
Comparisons
| Selector | Meaning | Compatibility/use case |
|---|---|---|
input:not([type="radio"]) | Every input except radios | Simple single exclusion |
input:not([type="radio"]):not([type="checkbox"]) | Every input except radios and checkboxes | Broadly compatible multiple exclusion |
input:not([type="radio"], [type="checkbox"]) | Every input except radios or checkboxes | Modern, concise selector-list syntax |
input[type="text"] | Only inputs explicitly marked type="text" | Precise but does not include omitted type attributes |
.form-field | Elements deliberately marked as form fields | Clear component-based styling |
A comma has different meanings depending on where it appears:
/* Selects either an input or a textarea */
input, textarea { }
/* Excludes an input matching either selector, in modern CSS */
input:not([type="radio"], [type="checkbox"]) { }
Cheat Sheet
/* Exclude one match */
input:not([type="radio"]) { }
/* Exclude several matches: compatible chained form */
input:not([type="radio"]):not([type="checkbox"]) { }
/* Exclude several matches: modern selector-list form */
input:not([type="radio"], [type="checkbox"]) { }
/* A class selector needs a dot */
.Copyform input { }
:not()selects elements that do not match its argument.- Chain multiple
:not()calls for broad compatibility. - A comma outside
:not()creates separate, alternative selectors. - Attribute selectors such as
[type="radio"]inspect the written HTML attribute. - Broad input selectors may also match
file,range,submit, and other non-text controls.
FAQ
Can :not() accept multiple arguments in CSS?
Modern CSS allows a comma-separated selector list inside :not(). For broader compatibility, chain separate :not() pseudo-classes instead.
How do I select inputs except radio buttons and checkboxes?
Use:
input:not([type="radio"]):not([type="checkbox"]) { }
Why is .Copyform different from Copyform in CSS?
.Copyform selects an element with class="Copyform". Copyform selects an element named <copyform>.
Does this selector include an input with no type attribute?
Yes. An input with no type attribute is not [type="radio"] or [type="checkbox"], so it matches. In HTML, it behaves as a text input by default.
Why might styling all non-radio inputs cause layout problems?
Other input types, including file, range, color, and submit, can match too. They may need their own styles.
Is input:not([type="radio"], [type="checkbox"]) valid CSS?
Yes, in modern CSS implementations. The chained form is preferable if older-browser compatibility is required.
Mini Project
Description
Build a small contact form whose text-entry fields share a consistent appearance while radio buttons and checkboxes keep their compact, choice-control layout. This demonstrates practical use of chained :not() selectors.
Goal
Style the text-entry controls in a form without applying those styles to radio buttons or checkboxes.
Requirements
Create a form with name, email, radio, checkbox, and submit inputs.
Apply shared field styling to inputs except radio buttons and checkboxes.
Use .Copyform as a class selector.
Give radio and checkbox controls their own compact styling.
Keep the form usable with visible labels.
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.
Apply CSS to an iframe: Same-Origin Styling in HTML
Learn why parent-page CSS does not style iframe content, how same-origin rules work, and practical ways to style embedded pages safely.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.