CSS Form Validation

Combine HTML5 constraint validation with CSS to provide clear, accessible feedback. Below are patterns for :valid/:invalid, delaying errors until the user types, parent highlighting with :has() (with a JS fallback), and inline messages using aria-live.

1) Email (required) with delayed errors


.input:invalid:not(:placeholder-shown){
  border-color: #fca5a5;
}
.field:has(.input:invalid:not(:placeholder-shown)) .error{
  display: block;
}

2) Password strength and confirmation


/* :has() can highlight parent when confirm doesn't match */
.field:has(#confirm:not(:placeholder-shown):invalid){
  background: #fff7f7;
}
Use uppercase, lowercase, numbers, and symbols.

3) Pattern validation (Indian mobile)


input[name="mobile"]{ letter-spacing: .5px; }
<input pattern="[6-9]\d{9}" title="Enter 10-digit number starting with 6-9">

Tip:

  • Use title to show a helpful tooltip for pattern rules.
  • Keep visible error text in the DOM (don’t rely only on tooltips).

4) Show all errors after submit (.was-validated)


.was-validated .input:invalid{
  border-color: #fca5a5;
}
/* JS adds .was-validated to the form if any field is invalid */

On submit, if invalid, the form gets .was-validated so all errors are visible.

Accessibility & Tips:

  • Pair inputs with <label for>. This improves focus and screen-reader support.
  • Use aria-live="polite" on inline error containers so updates are announced.
  • Delay error styling until users interact: :placeholder-shown helps avoid “red on page load”.
  • Highlight the whole field group using :has(); add a JS fallback class for older browsers.
  • Prefer native validation (required, type, pattern, min/max) and enhance with CSS; use JS only as a progressive enhancement.