A form is the moment in your product where the user has to do work. They have been browsing, reading, enjoying. Now you are asking them to type, choose, and submit. Make this moment painless and they will forgive almost any earlier friction. Make it painful and they will leave and never come back. This article covers the small set of habits that make forms feel easy.
The principles
Every form decision should answer one question: does this make the user more or less likely to finish? The right answer is almost always "more likely." That means fewer fields, clearer labels, smart defaults, inline validation, and a submit button that is impossible to miss.
The cardinal sin of form design is to treat the form as a database intake screen. "What would I like to know about this user?" is the wrong question. "What do I absolutely need to know to deliver value?" is the right one. Every field you remove is a small win.
Labels: the foundation
Every input needs a label. We covered this in HTML Forms for Beginners, but it is worth repeating: never rely on placeholder text alone. Placeholders disappear when the input is filled. Labels stay.
<label for="email">Email address</label>
<input name="email" type="email" />
For inline forms (a single search box at the top of a page), an aria-label can replace the visible label. For everything else, use a real <label>.
Help text: explain what is needed
If a field has rules the user might not guess, tell them upfront. Password fields are the classic example:
<label for="password">Password</label>
<input type="password" aria-describedby="pw-help" />
<p>Must be at least 8 characters with one number.</p>
The aria-describedby attribute connects the help text to the input. Screen readers read the label, then the help text. Visual users see both inline. Avoid help text that only appears on focus — the user might never focus the field, especially if they tab past it.
Placeholders are not labels
Placeholders look like labels but are not. They disappear when the user types, leaving the field looking blank. They are also typically low-contrast (grey on white), failing accessibility.
Use placeholders only for example values: placeholder="you@example.com" shows the user what an email looks like. Never as a substitute for a label.
Validation: inline, friendly, and forgiving
Validation should happen as the user types or moves between fields, not only on submit. The pattern:
- Validate on blur — when the user leaves a field, check it. If invalid, show the error inline.
- Clear the error as the user fixes it — once the input becomes valid, the error should disappear immediately.
- Show success subtly — a small green check after a valid field reassures the user.
Validate on the server too, even if you validate on the client. Client-side validation is for UX. Server-side is for security.
Error messages that help
Bad error messages tell the user they failed. Good error messages tell the user how to fix it.
- "Email is invalid" — bad.
- "Enter an email address in the format you@example.com" — good.
Place the error message directly below the field, near enough that the user sees both. Use red colour AND an icon AND a message — colour alone fails accessibility, as we discussed in Designing for Color Blindness.
The submit button
The submit button is the most important thing on the page. Treat it accordingly:
- Make it big enough to tap on mobile (at least 44x44px).
- Use a contrasting colour that stands out from the rest of the page.
- Label it with an action, not "Submit". "Create my account", "Send message", "Place order".
- Disable it after the first click to prevent double-submission, but only if the network request is in flight. Avoid permanently disabled buttons — they confuse users.
- Show a loading indicator inside the button during submission.
Smart defaults
The fewer decisions the user has to make, the more likely they are to finish. Smart defaults:
- Pre-fill the country based on IP geolocation (with a way to change it).
- Pre-check the "I agree to terms" checkbox — most users want to agree.
- Default the date picker to "today" or "tomorrow" for delivery forms.
- Default currency based on the user's locale.
Defaults reduce friction. Just make sure they are easy to override.
Multi-step forms
If your form has more than seven fields, consider breaking it into steps. Multi-step forms:
- Reduce the perceived effort (one small step at a time feels easier than one giant form).
- Allow progress to be saved (the user can come back later).
- Can validate per step (faster feedback, less frustrating).
Show progress: "Step 2 of 4 — Payment details". Let users go back to change earlier answers. Save their progress so a refresh does not lose everything.
Common pitfalls
- Too many fields. Every field costs completion rate. The median checkout has dropped from 11 fields to 8 over the last decade; the trend continues.
- Confusing field types. If you ask for a date, use a date picker, not a free-text input.
- Losing user input on error. If validation fails, preserve everything the user typed. Annoying to re-enter.
- Hiding required fields. Mark optional fields as optional. Required fields are the default.
- Asking for information you do not need. Phone number "in case we need to call you" — most apps do not need it. Remove it.
- No keyboard support. Tab between fields, Enter to submit, Escape to cancel. Test it.
A more advanced thing: real-time validation
For some fields (username availability, email deliverability), you can validate against the server as the user types. Debounce the input, send a small API request, and show feedback inline:
const input = document.querySelector("#username");
const status = document.querySelector("#username-status");
input.addEventListener("input", debounce(async () => {
const res = await fetch(`/api/check-username?q=${input.value}`);
const { available } = await res.json();
status.textContent = available ? "Available" : "Taken";
}, 300));
This pattern is great for usernames and slug fields. For passwords, never validate against the server — that is a security risk and a privacy violation.
The fields you should usually include
Beyond the basics, certain fields have well-established patterns:
- Email — single field, type="email", required. Allow plus-addressing (user+tag@example.com).
- Password — type="password" with a show toggle. Show password strength meters but do not block submission on weak passwords — that is a UX trap.
- Phone — include a country code selector. Format the number as the user types if you can. Most apps do not actually need phone numbers; remove if you can.
- Address — use a postcode lookup if available in your market. Typing a full address on mobile is painful.
- Payment — use a payment processor's hosted fields (Stripe Elements, Adyen) so you never touch the card data yourself.
For each field, ask: do I actually need this to deliver the service? If not, remove it. Every field is friction.
The mobile form
Mobile forms have unique challenges:
- Touch targets — minimum 44x44 pixels for any tappable element.
- Input types — use
type="email"to bring up the email keyboard,type="tel"for phone,inputmode="numeric"for numeric fields. Each shows a tailored keyboard that speeds entry. - Autofill — use
autocompleteattributes liberally.Further reading
Form UX is the intersection of accessibility standards, usability research, and good design judgement. The references below cover all three: MDN for the platform, WAI for accessibility, and Nielsen Norman Group for the underlying research.
- MDN accessibility section — MDN’s accessibility hub, with guides on building accessible forms, labelling inputs, and announcing errors to assistive technology.
- WAI-ARIA Authoring Practices — the W3C WAI guide to authoring accessible widgets, including form patterns, error handling, and keyboard interaction models.
- NN/g forms research — Nielsen Norman Group’s research articles on web forms, with evidence-based recommendations for layout, labels, and validation.
autocomplete="email",autocomplete="street-address". The browser's autofill will dramatically speed up mobile entry. - One thing per line — avoid side-by-side fields on narrow screens. Stack them vertically.
Test every form on a real phone. Emulators do not capture touch dynamics, keyboard behaviour, or the laggy reality of typing on glass.
When forms go wrong
Sometimes validation must block the user. The patterns for handling unavoidable errors:
- Show all errors at once after submit, with focus moved to the first error.
- Preserve all user input — never wipe a form on a validation error.
- Provide a clear path to fix: a list of what is wrong, with links to each field.
- Log the errors for your team to triage. If a specific field has a high error rate, the design is probably wrong.
A form that fails gracefully is a form the user might try again. A form that erases their work on error is a form they will leave.
FAQ
How many fields is too many?
There is no magic number, but research consistently shows that completion rate drops sharply after 7 to 10 fields in a single form. If you need more, split into steps or remove fields you do not actually need.
Should I show passwords by default?
No, but provide a "show password" toggle. Mobile keyboards are typo-prone, and users appreciate the option.
What about CAPTCHA?
Use it sparingly. Modern invisible CAPTCHA (Cloudflare Turnstile, reCAPTCHA v3) is much less intrusive than the old "type the distorted text" approach. If your form is high-value (account creation, payment), CAPTCHA is a reasonable trade-off. For low-value forms (contact us, newsletter), skip it.
How do I handle form abandonment?
Save progress as the user types (localStorage or server-side). When they come back, offer to resume. Send a follow-up email if you have one ("you left items in your cart"). The most common reason for abandonment is friction — fewer fields, faster submission, clearer errors.
Should I use a placeholder as a label on mobile?
No. Placeholders disappear on focus, which is exactly when mobile users most need the label. Always use a real <label>.
Iterate, test on real users, and refine the form until it feels effortless.
Refine the form until it is genuinely easy to use.
The form is where users decide whether to trust you. Make it effortless, and they will.
Iterate, test, repeat.
Iterate on the design, test on real users, and refine the form until it feels effortless to use.
Homework
Audit the sign-up form from the HTML Forms article and improve its UX:
- Remove any field you do not actually need.
- Add inline validation that fires on blur.
- Write better error messages that explain how to fix the issue.
- Add a visible focus style to every interactive element.
- Style the submit button to stand out and label it with an action ("Create my account").
- Test the form using only the keyboard.
Bonus: add a "show password" toggle on the password field. When you can ship a form that is genuinely easy, you have mastered form UX. For the accessibility implications, see Web Accessibility for Beginners.