What is the :invalid Pseudo-Class?
The :invalid CSS pseudo-class is a powerful selector that targets form elements whose contents fail to validate according to their HTML5 constraint rules. Part of the CSS Selectors Level 4 specification, :invalid enables visual feedback on user input without requiring JavaScript, making it an essential tool for creating accessible, user-friendly forms.
This pseudo-class automatically evaluates whether form controls meet their defined constraints--including required attributes, pattern matching, type-specific validation, and numeric range limits--allowing developers to style invalid states purely through CSS.
As part of modern web development best practices, leveraging native browser validation reduces JavaScript dependencies while improving performance and accessibility.
How :invalid Works
HTML5 introduced native form validation through the constraint validation API. Elements become invalid when they don't meet their specified constraints. The :invalid pseudo-class simply allows you to target and style these elements.
Validation Constraints That Trigger :invalid
- Required fields: Empty required inputs
- Pattern mismatches: Values not matching the
patternattribute regex - Type validation: Email, URL, number format violations
- Range limits: Values outside
min/maxbounds - Length violations: Values shorter/longer than
minlength/maxlength - Value type errors: Non-numeric input in number fields
The browser automatically applies validity states based on these constraints, and CSS pseudo-classes like :invalid and :valid reflect this state without any JavaScript required. This native validation approach is a cornerstone of progressive enhancement strategies.
Basic Syntax and Usage
The :invalid pseudo-class follows standard CSS selector syntax and can be combined with other selectors for precise targeting. It works on individual elements, entire forms, or groups of elements.
/* Basic syntax */
:invalid {
border-color: #dc3545;
}
/* Targeting specific input types */
input[type="email"]:invalid {
background-color: #fff5f5;
}
/* Form-level validation */
form:invalid {
outline: 2px solid #dc3545;
}
/* Chaining with other pseudo-classes */
input:focus:invalid {
box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.25);
}
By combining :invalid with other selectors like :focus or type-specific selectors, you create precise validation styling that responds to user interaction patterns.
The :user-invalid Alternative
A common issue with :invalid is that it immediately shows errors on page load--even before users have interacted with the field. This creates a poor first impression for forms with empty required fields.
The :user-invalid pseudo-class solves this by only applying styles after the user has engaged with the element. This provides a much better user experience for initial form states.
Key Differences
| Aspect | :invalid | :user-invalid |
|---|---|---|
| Timing | Immediate on page load | Only after user interaction |
| Initial State | Shows errors immediately | Clean initial state |
| Use Case | Real-time validation | Gentle validation feedback |
/* Better user experience with :user-invalid */
input:user-invalid {
border-color: #dc3545;
background-color: #fff5f5;
}
Live Form Demo: :invalid vs :user-invalid
Consider a registration form with three required fields: email, password confirmation, and phone number. Here's how the two pseudo-classes behave differently:
With :invalid:
- Page loads → All empty required fields immediately show red borders
- User hasn't typed anything yet, but form already looks "broken"
- Creates cognitive load before user engagement begins
With :user-invalid:
- Page loads → Clean form with no error indicators
- User types in one field → Validation triggers for that specific field
- User tabs away without completing → Error appears only then
- Provides space for users to understand the form before judgment
<!-- Live demo structure -->
<form class="user-friendly-form">
<input type="email" required placeholder="Enter email">
<input type="tel" required placeholder="Phone number">
<button type="submit">Register</button>
</form>
<style>
/* Aggressive validation */
.aggressive-form input:invalid {
border-color: #dc3545;
}
/* User-friendly validation */
.user-friendly-form input:user-invalid {
border-color: #dc3545;
}
</style>
Implementing :user-invalid is recommended for most forms, especially those with multiple required fields. It aligns with user-centered design principles by reducing initial friction and cognitive load.
Practical Examples
Email Validation
Email fields have specific validation requirements based on the HTML5 email type:
<form>
<label for="email">Email Address:</label>
<input
type="email"
id="email"
name="email"
required
placeholder="[email protected]"
>
<label for="url">Website:</label>
<input
type="url"
id="url"
name="url"
required
placeholder="https://yourwebsite.com"
>
<button type="submit">Submit</button>
</form>
Pattern-Based Validation
Use the pattern attribute for custom validation using regular expressions:
<!-- US Zip Code -->
<input
type="text"
pattern="[0-9]{5}"
title="Five digit zip code"
placeholder="12345"
>
<!-- Phone Number -->
<input
type="tel"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
title="Format: 123-456-7890"
placeholder="123-456-7890"
>
<!-- Password (at least 8 characters, 1 number) -->
<input
type="password"
pattern="^(?=.*[0-9])(?=.*[a-zA-Z]).{8,}$"
title="Must contain at least 8 characters and 1 number"
>
These patterns can be combined with CSS validation styling to create intuitive form experiences that guide users toward correct input.
Form-Level Validation
Apply :invalid to entire forms to control submission behavior:
/* Disable submit button until form is valid */
form:invalid button[type="submit"] {
opacity: 0.5;
pointer-events: none;
cursor: not-allowed;
}
/* Or show visual indicator on form */
form:invalid::before {
content: "Please fix the errors below";
display: block;
color: #dc3545;
margin-bottom: 1rem;
}
This approach is particularly useful for preventing premature form submission and reducing server-side validation load.
Accessibility Considerations
Critical: Color alone should not be the only indicator of invalid state. WCAG Success Criterion 1.4.1 requires that information not be conveyed through color alone, as users with color blindness may not perceive the visual cue.
Best Practices for Accessible Validation
- Combine color with icons or text
- Use ARIA attributes for screen reader support
- Provide descriptive error messages
- Manage focus appropriately
<!-- Accessible form with validation -->
<form>
<div class="form-group">
<label for="email">Email Address</label>
<input
type="email"
id="email"
name="email"
required
aria-invalid="true"
aria-describedby="email-error"
>
<span id="email-error" class="error-message">
Please enter a valid email address
</span>
</div>
</form>
/* Accessible invalid styling */
input[aria-invalid="true"] {
border-color: #dc3545;
background-image: url("data:image/svg+xml,...error-icon");
background-repeat: no-repeat;
background-position: right 10px center;
padding-right: 35px; /* Space for icon */
}
.error-message {
color: #dc3545;
font-size: 0.875rem;
display: block;
margin-top: 0.25rem;
}
Accessible form validation is a key component of inclusive web design. By combining visual and auditory feedback, you ensure all users can successfully complete forms.
Use :user-invalid for Better UX
Prevents showing errors on page load, only highlighting issues after user interaction with each field.
Pair Visual and Text Feedback
Combine color changes with error messages and icons to ensure all users understand validation issues.
Test with Assistive Technologies
Verify forms work correctly with screen readers, keyboard navigation, and other assistive tools.
Provide Clear Error Messages
Error text should explain what went wrong and how to fix it, not just indicate that something is wrong.
Consider Real-Time Validation Timing
Balance between immediate feedback and waiting until users finish typing to avoid frustrating interruptions.
Progressive Enhancement
Ensure forms work without JavaScript, using CSS validation as a baseline with enhancements built on top.
Browser Compatibility
The :invalid pseudo-class has excellent browser support across all modern browsers. It is considered "Baseline" available, meaning it works reliably across:
- Chrome (all versions)
- Firefox (all versions)
- Safari (all versions)
- Edge (all versions)
- Mobile browsers (iOS Safari, Chrome for Android)
Support has been consistent since July 2015, making :invalid a safe choice for production use without needing fallbacks for modern browsers.
Detection Approach
If you need to support very old browsers (which is rarely necessary today), you can use feature detection:
/* Feature detection for :invalid support */
@supports (selector(:invalid)) {
/* Styles for browsers with :invalid support */
input:invalid {
border-color: #dc3545;
}
}
@supports not (selector(:invalid)) {
/* Fallback styles or JavaScript-based validation */
.js .invalid-field {
border-color: #dc3545;
}
}
This broad compatibility makes CSS-based validation a reliable foundation for any web application.
Frequently Asked Questions
Conclusion
The :invalid pseudo-class is a fundamental tool for creating accessible, user-friendly forms in modern web development. By understanding how it works, when to use its :user-invalid variant, and how to combine visual styling with accessible error messaging, developers can create validation experiences that guide users effectively toward successful form submission.
Key takeaways:
- Use
:invalidfor immediate validation feedback and form-level checks - Consider
:user-invalidfor better initial user experience on page load - Always pair visual indicators with accessible error messages for all users
- Test across browsers and assistive technologies to ensure broad compatibility
- Combine CSS validation with JavaScript for advanced validation scenarios
Implementing proper form validation enhances user experience, reduces form abandonment, and improves conversion rates for your web applications. Start using :invalid in your forms today to create more intuitive, accessible validation experiences.
Sources
- MDN Web Docs - :invalid - The authoritative source for CSS pseudo-class documentation
- CSS-Tricks - :invalid - Practical developer resource with code examples
- ThatSoftwareDude - :user-valid and :user-invalid - Comparison of validation pseudo-classes
- W3C CSS Selectors Level 4 Specification - Official specification details
- WCAG 2.0 - Understanding Success Criterion 1.4.1 - Accessibility guidelines for color use