All resources
Form design & UX

Form UX: The Decisions That Actually Change Completion Rates

A practical guide to form UX: how many fields to ask for, real labels over placeholders, when to validate, error copy that helps, autocomplete and mobile keyboards.

The ShipMyForm team

· 12 min read

Five decisions decide whether people finish your form: how many fields you ask for, whether each one has a real label, when you show errors, what those errors say, and whether the browser is allowed to help. Everything else — spacing, corner radius, the wording on the button — is decoration on top of those five. This guide covers each one, plus the mobile and accessibility details that quietly break forms in ways you will never see in your own browser.

Full disclosure: ShipMyForm is our product, a form backend for static sites. The advice below is about markup and interaction design, and it applies whatever receives your submissions.

Every field you add is a cost

The single most effective change to any form is removing a field. Each one adds reading, a decision, a chance to get it wrong, and a chance to give up.

Two questions kill most fields:

  1. What decision changes based on this answer? If the answer is "none", or "we might want it later", delete it. Data you never act on is friction you charge every visitor for.
  2. Can we get it after they reply? A phone number, a company size, a budget range — these are all easier to ask in a reply to someone who has already written to you than in a form that has not yet earned anything.

A contact form usually needs a message, a way to reply, and enough identity to address the person. That is often two fields and a textarea.

The best evidence for the cost of length comes from checkout research, where the money makes the measuring worthwhile. Baymard Institute's benchmark (published April 2026) puts the average checkout at 19.9 form elements against an optimised flow of about 12, and finds 18 percent of people who abandon a purchase name a checkout that was too long or complicated. A contact form is not a checkout, but the mechanism is identical and the stakes for the visitor are lower, so their patience is shorter.

Where a field genuinely must exist, make it optional and say so explicitly. Mark optional fields rather than required ones when most of the form is required, because the rarer label is the one worth reading. Whichever you mark, never rely on an asterisk alone with no key explaining it.

Be suspicious of conversion-per-field tables:

You will find tables claiming an exact conversion rate for one field, three fields, five fields. We went looking for the source of the widely shared ones in September 2026 and could not find one. They disagree with each other, none publishes a dataset or a method, and they trace back to vendor and affiliate blogs rather than research. The direction is well supported. The numbers are not, and they are not transferable to your form. One form-analytics vendor is refreshingly blunt about the same question: the only way to know is to test it yourself.

Use a real label, always

A placeholder is not a label. It disappears the moment someone types, which is exactly when they need to check what the field wanted. Nielsen Norman Group has been making this case since 2014 and restated it in July 2025: placeholder text forces people to hold the question in short-term memory, its low contrast is hard to read, and a field that looks filled gets skipped.

html
<!-- No. The question vanishes as soon as they answer it. -->
<input type="email" name="email" placeholder="Email address" required />

<!-- Yes. The label stays; the placeholder shows format, not meaning. -->
<label for="email">Email address</label>
<input type="email" id="email" name="email"
       placeholder="[email protected]" autocomplete="email" required />

Two rules that follow from this:

  • Every control gets a label associated with it, either by wrapping the input in <label> or by matching for to the input's id. Clicking the label should focus the field. That is the quickest way to check you got it right.
  • Use the placeholder for format only, never for the question. DD/MM/YYYY is a good placeholder. Date of birth is a label pretending to be one.

Put labels above their fields. Nielsen Norman Group's recommendation is that the label sits immediately above the field on mobile and on shorter desktop forms, so the label and the input land in one fixation. Side labels are workable only when the labels are a similar length and sit close to their fields, which is rarely true of a form that has to survive translation.

Validate at the right moment

Validation timing is where forms feel hostile or helpful, and it costs nothing to get right. The rule is: never tell someone they are wrong before they have finished being right. Nielsen Norman Group puts the ideal as inline validation, with the indicator appearing as soon as the person has finished filling in the field. Finished is the operative word.

MomentWhat to do
While typing, first timeNothing. Validating on every keystroke means telling someone their email is invalid while they type the second letter
On blur, after they typed somethingValidate that field. This is the moment they consider it finished
While typing, after an error is shownRe-validate live, and clear the error the instant it becomes valid
On submitValidate everything, focus the first invalid field, and show every error at once
On the serverValidate again. Client-side checks are for humans, not for security

That last row is the one people skip. Anything enforced only in the browser can be bypassed with a single request, so client-side validation is a user experience feature and server-side validation is the actual rule. ShipMyForm runs server-side validation rules on the endpoint for exactly this reason.

Write errors that tell people what to do

An error message has one job: make the next action obvious. Most of them instead describe the failure and stop.

Instead ofSay
"Invalid input""Enter an email address, like [email protected]"
"Password does not meet requirements""Use at least 12 characters. You have 8"
"This field is required""Enter your full name"
"Error" (at the top, in red)Put the message next to the field it belongs to

Three mechanics matter as much as the wording:

  • Anchor the message to the field, visually and programmatically. Link them with aria-describedby so a screen reader announces the error when the field receives focus, and set aria-invalid="true" on the control.
  • Never use colour alone. Red text with no icon, no prefix and no wording change is invisible to a meaningful share of your visitors.
  • Keep what they typed. Clearing the form on a failed submit is the single most reliable way to lose someone. If the submission round-trips to a server, return their values with the errors.

Let the browser fill it in

Browsers and password managers will complete a form in one tap if you tell them what each field is. The autocomplete attribute is the cheapest usability win available, and most forms skip it.

Fieldautocomplete value
Full namename
Emailemail
Phonetel
Street addressstreet-address
Postcode / ZIPpostal-code
Countrycountry-name
Sign-in passwordcurrent-password
New passwordnew-password
SMS / authenticator codeone-time-code

The token list is normative, in the WHATWG HTML standard, so these are not conventions you can approximate. Use country-name for a readable country and country for a two-letter code. Getting them right also satisfies an accessibility requirement outright, WCAG success criterion 1.3.5, which is a rare case of one attribute closing two jobs at once.

one-time-code is worth calling out: it is what lets a phone offer the code from an SMS straight above the keyboard, turning the worst moment in most sign-in flows into a single tap.

Do not reach for autocomplete="off" to stop password managers. Browsers largely ignore it on login and payment fields precisely because sites misused it, so you get no control and lose the standard behaviour people expect. The legitimate use is narrow: a one-off field where a saved value would be actively wrong, such as a colleague's name on an internal form.

Get the mobile keyboard right

A large share of your submissions arrive from a phone, where the wrong keyboard turns a five second field into a fumble. Two attributes handle nearly all of it.

type sets the keyboard and the validation. type="email" gives an @ key, type="tel" gives a phone pad, type="url" gives a slash. Use them.

inputmode sets the keyboard without the validation, which is what you want for anything numeric that is not a quantity:

html
<!-- Card numbers, postcodes, OTP codes, reference numbers -->
<input inputmode="numeric" pattern="[0-9]*"
       autocomplete="one-time-code" name="code" />

<!-- Prices and measurements -->
<input inputmode="decimal" name="amount" />

Avoid type="number" for anything that is not a countable amount. This is not a matter of taste: Mozilla's own documentation says the number type should only be used for incremental numbers and is not appropriate for values that merely consist of digits, naming postal codes and credit card numbers directly. It also cannot use the pattern attribute, gives no feedback when someone types something that is not a number, and carries spinner arrows people can nudge by accident. A postcode is a string of digits, not a number you would do arithmetic on.

The 16px rule:

Safari on iOS zooms the page in when you focus an input whose font size is 15px or smaller, and it does not zoom back out. People then fill in the rest of your form while panning sideways. Set form controls to at least 16px, or 1rem, and it stops. Apple has never documented this, so treat it as long-standing WebKit behaviour rather than a specification, but it is still reproducible in 2026 and it is invisible on a desktop browser, which is why it ships so often. Do not reach for the old fix of disabling zoom in the viewport meta tag. Safari has ignored it since iOS 10, and blocking zoom is itself an accessibility failure.

One more mobile detail worth the minute it costs: keep the submit button reachable rather than stranded underneath a keyboard that has just opened.

One column, and when to split into steps

Put fields in a single column. Multi-column layouts make the eye choose a path at every row, and they collapse unpredictably at narrow widths. The exceptions are fields that read as one unit, like a city and postcode pair, and even then only above a breakpoint you have actually tested.

Group related fields with a <fieldset> and a <legend>. This is not decoration: for radio buttons and checkbox groups it is what tells assistive technology that the options belong to one question.

Splitting a long form into steps helps when it is genuinely long, when the questions fall into obvious groups, or when early answers change what you ask later. It hurts when it hides a short form behind extra clicks, or when it loses answers on a back button. If you do split it, show progress, let people go back without losing anything, and keep it one <form> element underneath. The multi-step form guide covers the markup and the Enter-key bug most tutorials ship.

The submit button is a state machine

The button has three states and most forms implement one.

Idle. Label it with the action, not the mechanism. "Send message" beats "Submit". A person should be able to read the button alone and know what is about to happen.

Submitting. Disable it on submit and say so, so a slow network does not produce three identical enquiries. Do not disable it before submit as a validation device, though. A button greyed out until the form is valid gives no reason why, so people are left hunting for the field they have not satisfied. Leave it enabled, let them press it, then show them exactly what is missing.

Done. Confirm in a way that survives a refresh. An inline success message that vanishes on reload leaves people wondering whether to send it again. Redirecting to a thank-you page also gives you something to track as a conversion. ShipMyForm supports both: a _redirect field for the page you want, or a JSON response if you are submitting with fetch.

Accessibility is the same work, done properly

Accessible forms are not a separate pass at the end. Almost every rule above is also a requirement of the Web Content Accessibility Guidelines, currently version 2.2, which became a W3C Recommendation in October 2023 and was republished with editorial corrections in December 2024. Version 3.0 is still a working draft and its own editors describe it as several years from done, so 2.2 is the standard to build against.

CriterionLevelWhat it means for a form
3.3.2 Labels or InstructionsAEvery control has a label, and formats are stated up front
3.3.1 Error IdentificationAErrors are described in text, not signalled by colour alone
3.3.3 Error SuggestionAAIf you know the fix, say it
1.3.5 Identify Input PurposeAACommon fields carry the right autocomplete token
2.5.8 Target Size (Minimum)AAPointer targets are at least 24 by 24 CSS pixels, with some exceptions
3.3.7 Redundant EntryAInformation already given in the same process is filled in or offered, not asked for again
3.3.8 Accessible Authentication (Minimum)AANo memory or puzzle test without an alternative, and let password managers paste

The last three arrived with WCAG 2.2 and are the ones most existing forms fail. Redundant Entry is why the "confirm your email" field is hard to justify unless re-entry is genuinely essential: it doubles typing for everyone to catch a mistake that a confirmation message catches for free. Accessible Authentication is why a challenge with no alternative route is now a conformance problem, not only an annoyance.

On target size, 24 by 24 CSS pixels is the floor at level AA. The 44 pixel figure you may have in mind is the stricter AAA criterion and Apple's own interface guidance. Aim above the floor where a mistap costs someone the form.

Do not make people prove they are human

Every CAPTCHA is a tax on real visitors to catch bots that increasingly solve them anyway. Spam is a real problem, but it is solvable on the server side, where it costs the visitor nothing: a honeypot field, rate limiting, and content classification stop the overwhelming majority of it invisibly. See stopping form spam without reCAPTCHA for how those layers fit together.

If your volume genuinely needs a challenge, use one that stays invisible for most visitors and offers an accessible alternative for the rest.

The checklist

code
Fields
  [ ] Every field changes a decision you will actually make
  [ ] Optional fields are marked, and the marker is explained
Labels
  [ ] Every control has a real label; clicking it focuses the field
  [ ] Placeholders show format, never the question
Validation
  [ ] Nothing is marked wrong before the field is left
  [ ] Errors clear as soon as the value becomes valid
  [ ] Submit focuses the first invalid field
  [ ] Every rule is enforced again on the server
Errors
  [ ] Each message says what to do next
  [ ] Messages sit next to their field, linked with aria-describedby
  [ ] A failed submit keeps everything they typed
Browser help
  [ ] autocomplete tokens on name, email, tel, address, password fields
  [ ] type and inputmode chosen per field; no type=number for codes
  [ ] Controls are at least 16px so mobile Safari does not zoom
Layout
  [ ] One column; related controls grouped in a fieldset with a legend
Submit
  [ ] Button names the action; disabled only while submitting
  [ ] Success survives a page refresh
Humans
  [ ] Spam handled server-side; no CAPTCHA without an alternative
Where this comes from:

Claims on this page were checked in September 2026 against primary sources: the WHATWG HTML standard for autocomplete tokens, Mozilla's documentation for inputmode and the number input type, WCAG 2.2 for the success criteria and their levels, Nielsen Norman Group for labels, placeholders and validation timing, and Baymard Institute's checkout benchmark for the field-count figures. Where a widely repeated claim had no traceable source, we have said so rather than repeat it.

Next steps

Frequently asked questions

What are the most important form UX best practices?
Ask for as few fields as you can act on, give every control a real label instead of a placeholder, validate on blur rather than on every keystroke, write errors that say what to do next, and add autocomplete and inputmode so the browser and the phone keyboard help. Those five decisions account for most of the difference between a form people finish and one they abandon.
How many fields should a contact form have?
As few as change a decision you will actually make. A contact form usually needs a message, an address to reply to, and a name, so two fields and a textarea. Anything you only might want later is easier to ask for in a reply to someone who has already written to you than in a form that has not earned anything yet.
Can I use placeholder text instead of labels?
No. A placeholder disappears the moment someone types, which is exactly when they need to check what the field asked for. It also breaks for people returning to a half-filled form and often has too little contrast to read. Use a real label associated with the control, and use the placeholder to show format, such as DD/MM/YYYY, not to ask the question.
When should a form show validation errors?
Validate a field when the person leaves it, not while they are still typing in it for the first time. Once an error is showing, re-check on every keystroke and clear it as soon as the value becomes valid. On submit, validate everything at once and move focus to the first invalid field. Repeat every rule on the server, because client-side checks are for humans and can be bypassed.
Should the submit button be disabled until the form is valid?
No. A disabled button gives no reason why, so people hunt for the field they have not satisfied. Leave it enabled, let them submit, and then show exactly what is missing next to each field. Do disable it while a submission is in flight, so a slow connection does not send the same enquiry three times.
Why does my mobile form zoom in when someone taps a field?
Mobile Safari zooms the page when an input's font size is under 16px, and it does not zoom back out afterwards. Set form controls to at least 16px, or 1rem, and it stops. The bug is invisible on a desktop browser, which is why it ships so often.
Do I need a CAPTCHA on my contact form?
Usually not. A CAPTCHA taxes every real visitor to catch bots that increasingly solve them anyway, and one with no alternative is a WCAG 2.2 accessibility failure. A honeypot field, rate limiting, and server-side content classification stop most form spam without the visitor noticing anything.

Related guides