Set the range.min="18" and max="60" define allowed values.
Enter a good number.25 sits inside the range.
Match :valid. The control gets the green border.
Out of range fails. Values like 10 match :invalid (and often :out-of-range).
Edge Cases & Pitfalls
If validity styles surprise you, check these first.
empty
Empty optional fields can be valid
An empty optional input with no failing constraints often matches :valid. That is expected.
load
Styles can appear before the user types
Empty required fields match :invalid on load. Prefer :user-valid / :user-invalid when you want feedback only after interaction.
color
Do not use color alone
Add text or icons with green/red borders so color-blind users still understand the state.
server
Client CSS is not enough
Always validate on the server. Users can bypass HTML constraints.
required
Required ≠ valid
:required means mandatory. Validity still depends on the value passing every constraint.
Compatibility
Browser Support
:valid is a browser CSS pseudo-class for constraint validation. Node.js, Deno, and Bun do not evaluate it.
✓ Baseline · Widely available since Jul 2015
:valid
Supported in Chrome 10+, Firefox 4+, Safari 5+, Edge 12+, Opera 10+, IE 10+. Works with HTML5 form constraints.
97%Global support
Google Chrome10+
Full support
Mozilla Firefox4+
Full support
Apple Safari5+
Full support
Microsoft Edge12+
Full support
Opera10+
Full support
Samsung Internet4+
Full support
Internet Explorer10+
Full support
:validWidely supported
Bottom line: Safe for production forms. Pair with :invalid and accessible, non-color cues.
Remember
Key Takeaways
Role: matches controls whose value passes HTML constraints.
Common use: green success borders next to :invalid errors.
vs :required: mandatory vs actually satisfying the rules.
Pitfall: empty required fields look invalid immediately on page load.
One line: use :valid to style form controls that currently pass their HTML constraints.
Frequently Asked Questions
It matches form controls whose current value passes HTML constraint validation — for example a well-formed email, a number in range, or a filled required field.
Constraints such as required, type (email, url, number), pattern, min, max, minlength, and maxlength. If every constraint passes, the control matches :valid.
:required only means the field is mandatory. :valid means the current value satisfies all constraints. An empty required field is :required but :invalid.
Yes. Use :valid for success cues and :invalid for error cues so users get clear feedback while typing.
Optional empty fields with no failing constraints typically match :valid. That is normal HTML constraint behavior.
Widely available since July 2015: Chrome 10+, Firefox 4+, Safari 5+, Edge 12+, IE 10+. It is a browser CSS selector, not a Node.js API.