The user-invalid and Validation Pseudo-classes
- CSS Basics
- Selectors & Specificity
- Box Model & Units
- Typography & Text Styling
- Colors & Color Spaces
- Positioning & Stacking Context
- Flexbox
- Grid
- Grid Advanced
- Responsive Design
- Container Queries
- Pseudo-classes & Pseudo-elements
- Modern Selectors
- CSS Custom Properties
- CSS Functions
- Transitions & Animations
- Transforms
- Forms & Input Styling
- CSS Architecture & Methodologies
- Accessibility in CSS
- Performance & Optimization
- View Transitions & Modern APIs
- Cascade Layers & Scope
The Basic :valid and :invalid Pseudo-classes
input:invalid {
border-color: red;
}These apply based on the browser's built-in validation - required fields, email format, pattern matching, and so on. The problem: :invalid often applies immediately, even before a user has had a chance to type anything, making an empty required field look like an error right from the start.
How :user-invalid Fixes This
input:user-invalid {
border-color: red;
}:user-invalid only applies once the user has actually interacted with the field - typically after they have typed something and then left it, or after a form submission attempt - avoiding the jarring experience of seeing error styling before any input has happened.
Its Counterpart: :user-valid
input:user-valid {
border-color: green;
}Similarly, :user-valid only applies once a field has been interacted with and found valid, rather than marking every field green by default before the user has done anything.
A Practical Validation Styling Pattern
input:user-invalid {
border-color: #dc2626;
}
input:user-valid {
border-color: #16a34a;
}
input:focus-visible {
outline: 2px solid #1d4ed8;
}Why This Matters for User Experience
Showing validation errors only after real interaction - rather than the instant a page loads - is a well-established usability principle. :user-invalid and :user-valid let this behavior be implemented in pure CSS, without needing JavaScript to manually track whether a field has been touched.