--- name: form-design description: Helper text, placeholders, validation and submit behaviour. Use when designing or reviewing a form, input field or data entry UI. metadata: priority: 8 pathPatterns: - "components/**" - "src/components/**" - "**/*.tsx" - "**/*.jsx" - "**/*.html" - "design-system/**" - "ui/**" promptSignals: phrases: - "form" - "input" - "validation" - "placeholder" - "helper text" - "field" - "submit" - "required" - "error message" - "fieldset" retrieval: aliases: - form design - input validation - helper text - placeholder - form validation - real-time validation - submit button state intents: - design a form - add validation to inputs - write helper text - enable submit when valid - add real-time validation - improve form usability examples: - add helper text to this input - validate this field in real time - disable the submit button until the form is valid - design this form with proper validation --- # Form Design Forms are where users give the product data. Every unnecessary obstacle between the user and a completed form is a failure. The design goal is to make correct input easy and incorrect input obvious — before the user submits. --- ## The Three Guidance Layers Each layer serves a distinct purpose. Do not collapse them. ### Layer 1 — Helper Text Explains *what* to enter. Appears below the input, always visible, in small secondary text. ``` Email address [ ] Use the email you signed up with. ``` - Write in plain language from the user's perspective - Keep it to one sentence — if you need more, the field is too complex or misnamed - Do not repeat the label ("Enter your email" below a label that says "Email" is redundant) - Helper text is not a replacement for a label — the label is still required ### Layer 2 — Placeholder Shows the *format* or an example value. Appears inside the input, disappears on typing. ``` [jane@example.com ] ``` - Use a realistic example, not a description: `+358 40 123 4567` not `Enter phone number` - Never use placeholder as a label — it disappears and leaves the user without context - Keep it grey (`--color-text-secondary`) and lighter than actual input text - Optional — not every field needs a placeholder ### Layer 3 — Validation Confirms whether the input is correct. The most important layer. ``` Email address [jane@ ] ← invalid ✗ Enter a valid email address. ``` **Validation timing:** - **On blur** (leaving the field): default for most fields — validates once the user has finished - **Real-time** (on input): use when the format is complex or the error is likely — password strength, IBAN, VAT number, URL, regex-heavy fields - **On submit**: catches anything missed, scrolls to the first error Real-time validation must be forgiving at the start — do not show an error the instant the user starts typing. Show it after a short debounce (300–500ms) or after the first character that makes the input definitively wrong. --- ## Submit Button State The submit button enables when the form is valid. This is one of the clearest affordance signals in form design — the user sees the goal and knows when they have reached it. ``` [Submit] ← disabled, low contrast, cursor: not-allowed (fields incomplete or invalid) [Submit] ← enabled, full colour, cursor: pointer (all required fields valid) ``` **Implementation:** ```html ``` For long or complex forms where real-time validation is not practical, do not disable the submit — validate on submit and scroll to errors instead. Disabled submit on a long form frustrates users who cannot tell what is missing. **Loading state on submit:** Replace label with spinner, disable the button. Prevent double-submission. --- ## Field Anatomy ``` [Label] [Optional badge if optional] [Input field ] [Helper text — what to enter, format, constraints ] [Error message — appears below helper text on validation fail ] ``` ```html
Finnish VAT numbers start with FI followed by 8 digits.
Enter a valid Finnish VAT number (e.g. FI12345678).