CSS :invalid Pseudo-Class
The CSS :invalid pseudo-class selects form controls that fail HTML constraint validation. It allows developers to highlight missing required values, incorrectly formatted entries, and values that do not meet defined limits.
:invalid Syntax
selector:invalid {
property: value;
}
The :invalid pseudo-class is added to a selector without a space. It matches form controls that currently fail one or more applicable validation constraints.
Basic Example
input:invalid {
border: 2px solid #cc3333;
}
This rule adds a red border to invalid input elements.
Email Inputs
input[type="email"]:invalid {
background-color: #fdeaea;
}
This rule applies a light red background when an email input fails validation.
Multiple Form Controls
input:invalid,
select:invalid,
textarea:invalid {
border-color: #cc3333;
}
This selector group styles invalid input, select, and textarea elements.
How :invalid Works
HTML provides built-in constraint validation for supported form controls. The browser evaluates the applicable rules and determines whether each control is valid or invalid.
HTML Example
<input type="email" required>
This input requires a nonempty value that follows the browser's email address validation rules.
CSS Example
input:invalid {
border-color: #cc3333;
}
The input matches :invalid when it is empty or contains an incorrectly formatted email address.
Automatic State Updates
The browser updates the validation state when relevant values or constraints change. CSS can respond without requiring JavaScript.
Validation Begins Before Submission
A required empty field can match :invalid as soon as the page loads. The selector does not wait for the user to submit the form.
Validation Does Not Submit the Form
The pseudo-class only provides a way to style the validation state. It does not submit data or replace the browser's validation process.
Validation Constraints
A form control can become invalid for several reasons, depending on its type and HTML attributes.
Common Validation Constraints
| Constraint | Example | Invalid Condition |
|---|---|---|
required |
required |
A required value or selection is missing. |
| Input type | type="email" |
The entered value does not satisfy the type's format rules. |
pattern |
pattern="[0-9]{5}" |
A nonempty value does not match the required pattern. |
minlength |
minlength="5" |
A user-entered value is shorter than the permitted length. |
maxlength |
maxlength="20" |
A user-entered value exceeds the permitted length, when such an entry is possible. |
min |
min="1" |
The value is below the permitted minimum. |
max |
max="10" |
The value exceeds the permitted maximum. |
step |
step="2" |
The value does not satisfy the permitted step interval. |
| Custom validity | setCustomValidity() |
A custom validation error is active. |
Multiple Constraints
A control can violate more than one constraint at the same time. The :invalid pseudo-class matches whenever at least one applicable constraint fails.
Constraints Depend on Input Type
Not every attribute applies to every form control. For example, min and max apply to supported numeric and date-related inputs, not ordinary text inputs.
Required Fields
The required attribute makes a value or selection mandatory for supported form controls.
HTML
<label for="username">Username:</label>
<input type="text" id="username" required>
CSS
input:required:invalid {
border-color: #cc3333;
}
The input matches this selector while its required value is missing.
Initial Invalid State
A required input can be invalid before the user interacts with it. Consider using :user-invalid when validation feedback should appear only after relevant user interaction.
Optional Fields
An optional field is not invalid merely because it is empty. However, it can become invalid when a nonempty value violates another applicable constraint.
Input Formats
Some form controls validate the format of entered values automatically.
Email Input
<input type="email" required>
A nonempty value must satisfy the browser's email input format requirements.
URL Input
<input type="url" required>
A nonempty value must satisfy the browser's URL input format requirements.
Pattern Validation
<input type="text" pattern="[0-9]{5}" title="Enter five digits">
A nonempty value must contain exactly five digits to satisfy this pattern.
CSS
input:invalid {
border-color: #cc3333;
background-color: #fdeaea;
}
The same CSS selector can respond to different validation failures without needing separate rules for each constraint.
Range Validation
Number and date-related inputs can use minimum and maximum constraints.
Number Input
<input type="number" min="1" max="10" value="15">
The value 15 exceeds the maximum of 10, so the input matches :invalid.
CSS
input:out-of-range {
border-color: #cc3333;
}
input:invalid {
background-color: #fdeaea;
}
The input matches both selectors because its value is outside the permitted range and therefore invalid.
Step Mismatch
<input type="number" min="0" max="10" step="2" value="3">
The value 3 is within the permitted range but violates the step constraint. The input can match both :in-range and :invalid.
Range vs. Overall Validity
Use :out-of-range specifically for range violations and :invalid for overall constraint validation failures.
:invalid vs. :valid
The :invalid and :valid pseudo-classes represent opposite constraint validation states.
Comparison
| Selector | Matching Condition |
|---|---|
:invalid |
The control fails at least one applicable validation constraint. |
:valid |
The control satisfies all applicable validation constraints. |
CSS Example
input:valid {
border-color: #008000;
}
input:invalid {
border-color: #cc3333;
}
The border color changes according to the control's current validation state.
A Valid Field May Be Empty
An empty optional input can be valid because it does not violate a required-value constraint.
Avoid Premature Success Messages
Do not assume that every control matching :valid contains a completed entry. Use additional conditions when necessary.
:invalid vs. :user-invalid
The :user-invalid pseudo-class provides a way to display validation feedback after relevant user interaction.
Comparison
| Selector | Matching Condition |
|---|---|
:invalid |
The control currently fails validation, including before user interaction. |
:user-invalid |
The control is invalid and the browser determines that user interaction warrants displaying invalid feedback. |
CSS Example
input:user-invalid {
border-color: #cc3333;
background-color: #fdeaea;
}
This selector can help avoid displaying an error appearance on untouched required fields.
When to Use Each
Use :invalid when styling must reflect the current validation state immediately. Use :user-invalid when feedback should depend on user interaction.
Browser Behavior
The exact timing of :user-invalid matching can vary according to the control and browser interaction behavior.
Form and Fieldset States
The :invalid pseudo-class can also match form-related elements based on the validation state of their associated controls.
Form Example
<form>
<label for="email">Email:</label>
<input type="email" id="email" required>
<button type="submit">Submit</button>
</form>
CSS
form:invalid {
border-left: 4px solid #cc3333;
}
The form can match :invalid when one or more associated controls fail constraint validation.
Fieldset Example
fieldset:invalid {
border-color: #cc3333;
}
A fieldset can match :invalid when a control it contains fails validation.
Styling with :has()
.form-group:has(input:invalid) {
border-left: 3px solid #cc3333;
}
The :has() relational pseudo-class can style a container when it contains an invalid input.
:invalid Specificity
The :invalid pseudo-class contributes a specificity of 0-1-0.
Specificity Examples
| Selector | Specificity |
|---|---|
:invalid |
0-1-0 |
input:invalid |
0-1-1 |
.field:invalid |
0-2-0 |
input[type="email"]:invalid |
0-2-1 |
#email:invalid |
1-1-0 |
Specificity Example
input {
border: 2px solid #ccc;
}
input:invalid {
border-color: #cc3333;
}
When both selectors match and other cascade factors are equal, the :invalid rule takes precedence because it has greater specificity.
Practical Uses
The :invalid pseudo-class is commonly used to highlight form controls that require correction.
Required Fields
Highlight required fields that have not been completed.
Email Validation
Identify email inputs containing values that do not satisfy the browser's format rules.
Number Limits
Provide feedback when a numeric value falls outside permitted limits or violates a step constraint.
Pattern Matching
Highlight values that do not match a required format, such as a five-digit code.
Form-Level Styling
Apply visual feedback to a form or fieldset when one or more controls are invalid.
Limitations
The :invalid pseudo-class reflects HTML constraint validation but does not replace complete data validation.
May Match Before Interaction
Required empty fields can match :invalid immediately when the page loads.
Not Every Control Participates
Some controls do not participate in constraint validation. For example, disabled controls are excluded, and readonly controls are barred from constraint validation.
Browser Validation Is Limited
Built-in validation checks supported constraints, but it cannot determine whether every entered value is accurate or appropriate for an application.
CSS Does Not Display Error Messages
The pseudo-class can style an invalid control, but clear explanations may require additional HTML or JavaScript.
Server Validation Is Required
Client-side validation can be bypassed. Submitted data must also be validated on the server.
Accessibility
Validation feedback should help users understand which fields need correction and why.
Do Not Rely on Color Alone
Red borders can indicate invalid fields visually, but error messages should also explain the problem in text.
Provide Descriptive Labels
Associate each control with a visible <label> element.
Explain Validation Requirements
Describe required formats, minimum lengths, and permitted ranges before users submit the form.
Accessible Error Messages
When displaying custom errors, associate the error message with the control using appropriate attributes such as aria-describedby.
Avoid Immediate Error Overload
Consider :user-invalid to delay error styling until the user has interacted with a field.
Maintain Focus Visibility
Preserve clear keyboard focus indicators when applying validation styles.
Best Practices
- Use
:invalidto style controls that fail HTML constraint validation. - Define appropriate validation rules using HTML attributes.
- Use
:user-invalidwhen error styling should appear after user interaction. - Use
:out-of-rangewhen targeting range violations specifically. - Provide clear labels and explain validation requirements.
- Do not rely on color alone to communicate errors.
- Preserve keyboard focus indicators.
- Validate submitted data on the server.
:invalid Example
This example uses a required email input and a number input with permitted values from 1 through 10. Invalid values receive a red border and light red background. Change the values to see the styles update automatically.
HTML
<div class="invalid-demo">
<label for="email">Email Address:</label>
<input type="email" id="email" placeholder="name@example.com" required>
<label for="quantity">Quantity (1 to 10):</label>
<input type="number" id="quantity" min="1" max="10" value="5" required>
<p>Enter an invalid email or a number outside the allowed range.</p>
</div>
CSS
.invalid-demo label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.invalid-demo input {
display: block;
box-sizing: border-box;
width: 100%;
max-width: 250px;
margin-bottom: 12px;
padding: 8px;
border: 2px solid #ccc;
border-radius: 4px;
}
.invalid-demo input:invalid {
border-color: #cc3333;
background-color: #fdeaea;
}
.invalid-demo input:valid {
border-color: #008000;
background-color: #e8f5e9;
}
.invalid-demo input:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
Browser Result
Note: The required email input starts in an invalid state because it is empty. The number input starts valid with a value of 5. Both controls update their appearance as their values change.
Browser Support
Baseline: Widely available. The :invalid pseudo-class is supported in modern versions of Chrome, Edge, Firefox, Safari, and other major browsers.
For current compatibility information, visit Can I Use? and search for :invalid.
Specifications
The :invalid pseudo-class is defined in CSS Selectors Level 4. The HTML Living Standard defines how constraint validation determines whether form controls are valid or invalid.
