Detailed explanation
CSS validation pseudo-classes let you style controls according to the browser’s built-in HTML constraint validation, rather than manually adding error classes. Constraints come from attributes such as required, type="email", pattern, min, and max. For example, input:invalid { border-color: red; } highlights controls that fail an applicable constraint, while input:valid { border-color: green; } highlights those that pass. This provides live visual feedback without JavaScript, but it does not replace server-side validation or explain an error to the user by itself.
Under the hood, the browser evaluates a control’s value against its applicable constraints and updates pseudo-class matching as its state changes. An empty required text input is invalid; an empty optional email input is generally valid, but a non-empty malformed email address is invalid. The :required and :optional pseudo-classes describe whether a supported control has the required attribute, not whether its current value is acceptable. You can therefore distinguish mandatory fields with input:required while independently styling their validity. These selectors also work with supported select and textarea controls, although individual constraints depend on the element and input type.
A key usability issue is timing: :invalid can match before someone has interacted with the form. Where supported, :user-invalid and :user-valid provide feedback after user interaction, with activation details determined by the browser. Another common pattern is input:invalid:not(:placeholder-shown), which suppresses invalid styling while placeholder text is displayed. However, :placeholder-shown is not a universal empty-value check: it requires a control that supports placeholders and is actually displaying one. With the supplied rules, input:required:placeholder-shown has greater specificity than input:invalid, so its orange border wins for an empty required input showing a placeholder.
In an interview, connect selector mechanics to accessible feedback and predictable states. Keep visible labels, preserve focus indicators, and pair colour with meaningful text or another non-colour cue. CSS can style existing help text, but application logic may be needed to update specific error messages and accessibility attributes. Also explain that passing browser constraints only establishes client-side validity; the server must still validate submitted data, including business rules and security checks.
Key points to remember
- :valid and :invalid reflect applicable HTML constraint validation results.
- :required and :optional indicate required status, not validity.
- :placeholder-shown matches displayed placeholder text, not every empty control.
- :user-invalid and :user-valid help delay feedback until user interaction; check target-browser support.
- Use accessible error messages alongside styling, and always validate on the server.
Common mistakes candidates make
- Showing every required field as an error immediately on page load without considering interaction timing.
- Treating :placeholder-shown as a universal emptiness detector or :optional as equivalent to :valid.
- Relying only on red and green borders, or assuming CSS validation makes submitted data trustworthy.
Likely follow-up questions
How can you avoid showing errors before the user interacts with a field?
Use :user-invalid where supported to tie invalid styling to browser-defined interaction behaviour. The :invalid:not(:placeholder-shown) pattern can suppress errors while a placeholder is visible, but it does not reliably track whether a field has been touched.
Does adding novalidate to a form stop :invalid from matching?
No. novalidate disables interactive constraint validation during form submission, but controls can still match :valid and :invalid according to their constraints.
Can CSS validate whether two password fields match?
CSS cannot generally compare the values of two controls. Use JavaScript to compare them and call setCustomValidity() on the confirmation field; a non-empty message makes it invalid, and an empty string clears that custom error.
Interview tip: Explain the constraint-to-pseudo-class relationship first, then demonstrate one selector and discuss feedback timing and accessibility.
