Build forms that users complete without confusion, anxiety, or abandonment. The goal is not to collect every possible field; it is to remove every unnecessary obstacle between the user and their goal.
Consult the form validation patterns reference for validation timing, error placement, multi-field dependencies, async validation, and recovery design.
Consult the live validation UX reference for blur-vs-real-time timing, reward-early/punish-late behavior, and copy-paste-friendly validation.
Consult the error recovery reference for what happens after validation or submission fails.
Consult the disabled buttons UX reference when deciding whether to block submit buttons or keep them enabled with error explanation.
Consult the component anatomy reference for button, input, checkbox, radio, toggle, dropdown, and textarea anatomy guidance.
MANDATORY PREPARATION
Users start this workflow with /forms. Once this skill is active, load $frontend-design — it contains design principles, anti-patterns, and the Context Gathering Protocol. Follow that protocol before proceeding — if no design context exists yet, you MUST load $setup first. Additionally gather: what goal the user is trying to achieve, which fields are truly required, and what causes abandonment in the current flow.
Assess Form Needs
Understand the form's purpose and context:
- User goal: What does the user get by completing this form? The clearer the payoff, the higher the completion rate.
- Field necessity: Every field you add drops completion rates. Challenge each field: is it required now, or can it be collected later?
- Context of use: Is the user rushed, distracted, on mobile, or in a stressful situation? Stressful contexts need simpler forms.
- Failure points: Where do users currently drop off? Long forms, unclear labels, and unexpected validation are common culprits.
Form Structure
Field order
- Ask easy questions first to build momentum
- Group related fields visually (name fields together, address fields together)
- Place optional fields at the end or mark them clearly
- Separate billing and shipping only when they are genuinely different
Label design
- Use clear, scannable labels above the input (not inside as placeholder text)
- Sentence case is easier to read than Title Case
- Be specific: "Card number" not "Payment info"
- Helper text should explain format requirements, not repeat the label
Input design
- Match input width to expected content (postal code fields should not be full-width)
- Use the appropriate input type (
type="email", type="tel", type="date") for mobile keyboard optimization
- Show formatting hints as the user types (credit card spacing, phone number grouping)
- Autofill-friendly: use standard
name and autocomplete attributes
Multi-step forms
Break long forms into steps when:
- There are more than 6-8 fields
- The form covers distinct topics (account info, payment, confirmation)
- Users need to review before final submission
Step design:
- Show progress ("Step 2 of 4") so users know what remains
- Allow navigation back to previous steps
- Preserve entered data if the user leaves and returns
- Validate each step before allowing progression, but do not block navigation backward
Validation Strategy
Timing
- Validate on blur for clearly completed fields (email, phone, format-required fields)
- Validate on input only for immediate feedback that helps (password strength, character count)
- Validate on submit for everything else, especially cross-field dependencies
- Never validate a pristine field; it creates anxiety
Error design
- Place error messages directly below the field
- Explain what went wrong and how to fix it
- Use
aria-invalid and aria-describedby for screen reader association
- Preserve all user input when validation fails
- Move focus to the first error after failed submission
Success states
- Subtly confirm valid fields with a checkmark or green border
- Remove success indicators when the user edits the field again
- Do not celebrate every valid field; it becomes noise
Mobile Form UX
- Ensure touch targets are at least 44×44px
- Use appropriate input types for optimized keyboards
- Minimize scrolling by breaking into steps or using progressive disclosure
- Show the numeric keyboard for number fields, email keyboard for email fields
- Avoid dropdowns for short lists; use radio buttons or segmented controls instead
Accessibility
- Associate every input with a label using
for/id
- Use
fieldset and legend for grouped fields
- Announce form-level errors with
role="alert" or aria-live="polite"
- Ensure error messages are programmatically associated with fields
- Test keyboard navigation through the entire form
- Do not rely on color alone for error indication
Anti-Patterns
- Too many fields: Every additional field reduces completion rates
- Placeholder as label: Disappears when the user types; bad for memory and accessibility
- Validate on load: Pristine fields showing errors feel accusatory
- Vague errors: "Invalid input" without explanation leaves users guessing
- Clearing fields on error: Losing typed data is deeply frustrating
- Disabled submit without guidance: A grayed-out button with no visible errors is a dead end
- Multi-step without progress indicator: Users do not know how much remains
- Inconsistent validation timing: Some on blur, some on submit, with no clear logic
- Ignoring mobile keyboards: Using
type="text" for phone numbers forces users to switch keyboards
- No save-and-resume: Long forms that cannot be saved mid-progress punish interruptions
Verify Form Quality
Before shipping:
1---2name: forms3description: Design, structure, or improve form interfaces for clarity, completion rates, and user confidence. Use when the user asks to build a form, redesign a form flow, improve form conversion, add multi-step forms, fix form UX, or structure field layouts and validation.4---5
6Build forms that users complete without confusion, anxiety, or abandonment. The goal is not to collect every possible field; it is to remove every unnecessary obstacle between the user and their goal.
7
8Consult the [form validation patterns](../frontend-design/reference/form-validation-patterns.md) reference for validation timing, error placement, multi-field dependencies, async validation, and recovery design.
9Consult the [live validation UX](../frontend-design/reference/live-validation-ux.md) reference for blur-vs-real-time timing, reward-early/punish-late behavior, and copy-paste-friendly validation.
10Consult the [error recovery](../frontend-design/reference/error-recovery.md) reference for what happens after validation or submission fails.
11Consult the [disabled buttons UX](../frontend-design/reference/disabled-buttons-ux.md) reference when deciding whether to block submit buttons or keep them enabled with error explanation.
12Consult the [component anatomy](../frontend-design/reference/component-anatomy.md) reference for button, input, checkbox, radio, toggle, dropdown, and textarea anatomy guidance.
13
14## MANDATORY PREPARATION
15
16Users start this workflow with `/forms`. Once this skill is active, load $frontend-design — it contains design principles, anti-patterns, and the **Context Gathering Protocol**. Follow that protocol before proceeding — if no design context exists yet, you MUST load $setup first. Additionally gather: what goal the user is trying to achieve, which fields are truly required, and what causes abandonment in the current flow.
17
18## Assess Form Needs
19
20Understand the form's purpose and context:
21
221. **User goal**: What does the user get by completing this form? The clearer the payoff, the higher the completion rate.
232. **Field necessity**: Every field you add drops completion rates. Challenge each field: is it required now, or can it be collected later?
243. **Context of use**: Is the user rushed, distracted, on mobile, or in a stressful situation? Stressful contexts need simpler forms.
254. **Failure points**: Where do users currently drop off? Long forms, unclear labels, and unexpected validation are common culprits.
26
27## Form Structure
28
29### Field order
30
31- Ask easy questions first to build momentum
32- Group related fields visually (name fields together, address fields together)
33- Place optional fields at the end or mark them clearly
34- Separate billing and shipping only when they are genuinely different
35
36### Label design
37
38- Use clear, scannable labels above the input (not inside as placeholder text)
39- Sentence case is easier to read than Title Case
40- Be specific: "Card number" not "Payment info"
41- Helper text should explain format requirements, not repeat the label
42
43### Input design
44
45- Match input width to expected content (postal code fields should not be full-width)
46- Use the appropriate input type (`type="email"`, `type="tel"`, `type="date"`) for mobile keyboard optimization
47- Show formatting hints as the user types (credit card spacing, phone number grouping)
48- Autofill-friendly: use standard `name` and `autocomplete` attributes
49
50### Multi-step forms
51
52Break long forms into steps when:
53- There are more than 6-8 fields
54- The form covers distinct topics (account info, payment, confirmation)
55- Users need to review before final submission
56
57**Step design**:
58- Show progress ("Step 2 of 4") so users know what remains
59- Allow navigation back to previous steps
60- Preserve entered data if the user leaves and returns
61- Validate each step before allowing progression, but do not block navigation backward
62
63## Validation Strategy
64
65### Timing
66
67- Validate on blur for clearly completed fields (email, phone, format-required fields)
68- Validate on input only for immediate feedback that helps (password strength, character count)
69- Validate on submit for everything else, especially cross-field dependencies
70- Never validate a pristine field; it creates anxiety
71
72### Error design
73
74- Place error messages directly below the field
75- Explain what went wrong and how to fix it
76- Use `aria-invalid` and `aria-describedby` for screen reader association
77- Preserve all user input when validation fails
78- Move focus to the first error after failed submission
79
80### Success states
81
82- Subtly confirm valid fields with a checkmark or green border
83- Remove success indicators when the user edits the field again
84- Do not celebrate every valid field; it becomes noise
85
86## Mobile Form UX
87
88- Ensure touch targets are at least 44×44px
89- Use appropriate input types for optimized keyboards
90- Minimize scrolling by breaking into steps or using progressive disclosure
91- Show the numeric keyboard for number fields, email keyboard for email fields
92- Avoid dropdowns for short lists; use radio buttons or segmented controls instead
93
94## Accessibility
95
96- Associate every input with a label using `for`/`id`
97- Use `fieldset` and `legend` for grouped fields
98- Announce form-level errors with `role="alert"` or `aria-live="polite"`
99- Ensure error messages are programmatically associated with fields
100- Test keyboard navigation through the entire form
101- Do not rely on color alone for error indication
102
103## Anti-Patterns
104
105- **Too many fields**: Every additional field reduces completion rates
106- **Placeholder as label**: Disappears when the user types; bad for memory and accessibility
107- **Validate on load**: Pristine fields showing errors feel accusatory
108- **Vague errors**: "Invalid input" without explanation leaves users guessing
109- **Clearing fields on error**: Losing typed data is deeply frustrating
110- **Disabled submit without guidance**: A grayed-out button with no visible errors is a dead end
111- **Multi-step without progress indicator**: Users do not know how much remains
112- **Inconsistent validation timing**: Some on blur, some on submit, with no clear logic
113- **Ignoring mobile keyboards**: Using `type="text"` for phone numbers forces users to switch keyboards
114- **No save-and-resume**: Long forms that cannot be saved mid-progress punish interruptions
115
116## Verify Form Quality
117
118Before shipping:
119
120- [ ] Every field is justified; optional fields are clearly marked
121- [ ] Labels are clear, specific, and above the input
122- [ ] Validation does not trigger on pristine fields
123- [ ] Errors explain what went wrong and how to fix it
124- [ ] Input is preserved when validation fails
125- [ ] Focus moves to the first error after failed submission
126- [ ] Multi-step forms show progress and allow backward navigation
127- [ ] Mobile keyboards are optimized per field type
128- [ ] The form is fully keyboard-navigable
129- [ ] Color is not the only indicator of error or success