/forms
Use it when validation, errors and required fields are fighting the user.
npx skills add rshokhnur/skillsForms are where interfaces are least forgiving, because the user has already agreed to do work and the only remaining variable is how much you waste.
Validate on blur, not on keystroke
Validating as someone types means telling them their email is invalid while they are still typing it. Validate when they leave the field, and re-validate on every keystroke after it has failed once — so the error clears the moment it is fixed rather than on the next blur.
Errors say what to do
“Invalid input” describes your code’s opinion. “Use the format 07/2029” describes the user’s next action. Put the message next to the field, never only at the top, and never only in colour — a red border alone is invisible to a colourblind user and to anyone in a hurry.
Mark the shorter set
If most fields are required, mark the optional ones. Asterisking eleven of twelve labels is noise that hides the one fact that mattered.
The details that cost nothing
- Real
<label>elements, not placeholders. Placeholder-as-label vanishes exactly when the user needs to check what they typed. font-size: 16pxminimum on inputs, or iOS zooms the page on focus.- Correct
typeandautocomplete— this is the single highest-leverage line in any form. - Submit stays enabled. A disabled button with no explanation is a dead end; let them press it and tell them what is missing.
Patterns · Jul 2026