forms-validationlisted
Install: claude install-skill soumit-kaz/lazysitter
# Forms and validation
Forms are where accessibility, state management and error handling all meet, and where losing the user's work is most costly.
## Labelling
- **Every control has a real `<label>`** with `htmlFor` matching the input's `id`, or wrapping it. A placeholder is **not** a label — it disappears exactly when the user needs it, and it fails contrast requirements in most designs.
- **Group related controls** with `<fieldset>` + `<legend>` — radio groups especially, where the group's question is otherwise never announced.
- **Mark required fields in text**, not by an asterisk alone (`aria-required` plus a visible convention explained once).
- **Hint text** is associated with `aria-describedby`, so it is announced with the field rather than orphaned near it.
## Validation timing — the part that most often annoys users
- **Do not validate on every keystroke while first typing.** Telling someone their email is invalid at `j@` is noise.
- **Validate on blur** for the field just left, **and on submit** for everything.
- **Once a field has an error, re-validate on change** so the error clears as soon as it is fixed. Making the user submit again to learn they fixed it is the worst of both.
- **Async validation** (username availability) needs debouncing, a pending state, and a guard against out-of-order responses — the same request-ordering problem as any fetch.
## Error association and announcement
Three things must be true for every error:
1. **`aria-invalid="true"