Design CraftForms

Form design mistakes that are still everywhere

Forms are where most products lose users. The same mistakes recur so reliably they might as well be defaults.

A checkout flow that loses 30% of users at the payment step has a form problem. A sign-up flow with 60% drop-off after email entry has a form problem. Forms are where products lose users, and they lose them in ways that are almost always preventable. The mistakes aren't subtle; they've just been normalized.

The patterns below aren't edge cases. They're defaults that shipped, stayed, and never got questioned.

Labels that disappear when you need them

Placeholder text as a label looks clean in a mockup. In use, it disappears the moment someone starts typing. Now the user has a form field with text in it and no indication of what the field is for.

The workaround is placeholder text that's less than a label: a hint, an example, a format suggestion. "e.g. john@email.com" in a field labeled "Email address" is a placeholder. "Email address" used as the placeholder instead of a label is a design problem dressed up as a design decision.

Floating labels (labels that shrink and move up when the field activates) solve the disappearing-label problem while preserving the clean appearance. They work, but they require careful implementation: the floating label needs to be visible and readable at its resting size, the animation can't be jarring, and the timing has to feel right. Done poorly, they're worse than static labels. Done well, they're a reasonable compromise.

Static labels above the field remain the most reliable pattern. Less visually elegant, always legible. If the form's visual complexity concerns you, the answer is usually to reduce the number of fields, not to hide the labels.

Inline validation that fires too early

Showing an error while someone is still typing is aggressively unhelpful. The user has typed three characters into an email address field and is presented with "Invalid email format." They know. They're not done.

The right timing for inline validation is on blur: when the user moves out of the field. This gives them a chance to finish what they were doing before being corrected. If they come back and fix it, clear the error as soon as the value is valid. Don't wait for blur again. Clearing the error in real time while the user types is fine. Showing the error in real time while they type is not.

There's a specific failure mode for password fields: the "strength meter" that starts red before the user has typed anything, or that flips to weak the moment they type a single character. A strength meter that starts from zero as soon as the field is touched is a meter that reflects current state, not helpful feedback. Password strength feedback should appear after the user has paused or moved on, and should be constructive ("Add a number or symbol") rather than evaluative ("Weak").

Required vs optional: the inverted default

Most forms mark required fields with an asterisk and leave optional fields unmarked. This means users have to remember the convention, apply it to every field, and assume that anything without an asterisk can be skipped.

A better approach is to mark optional fields as optional and leave required fields unmarked. If 80% of your form fields are required, as is the case in most sign-up and checkout flows, then the asterisks are marking the majority of the form with a special indicator, which is counterproductive. Marking the few optional fields as "(optional)" is clearer and requires less mental overhead.

The asterisk convention also silently excludes any user who doesn't know what it means. "Optional" written out in small text leaves no ambiguity.

Two columns when one would do

Two-column form layouts appear because they make forms look shorter. They don't make forms faster to complete. Research on form completion time consistently shows that single-column forms are completed faster: the eye follows a single vertical path instead of needing to track left and right.

Two-column layouts are appropriate when two fields genuinely belong side by side: first name and last name, city and state or province, start date and end date. Fields that are semantically related and similar in character length can share a row without creating confusion.

Two-column layouts are not appropriate for fields that happen to be short: putting "Phone number" and "Job title" side by side doesn't help anyone. It just makes the form look like a spreadsheet.

Submission failures with no explanation

A form that fails to submit and says "Something went wrong, please try again" has told the user nothing useful. Should they check their connection? Change a field value? Wait? Try a different browser?

Error messages on form submission need to do two things: identify what failed, and explain what to do about it. "Your session has expired: please reload and try again" is a good error message. "Error 500" is not an error message; it's a system log.

Field-level errors after submission are a different problem. The pattern of clearing all field-level errors on submission and then re-rendering them after the response returns is disorienting. If the user has already corrected a field and the error reappears after submit, they have to figure out whether their correction was ignored or whether the server found a different problem.

The cleaner pattern is to re-validate locally on submit before sending anything, scroll to the first error, and hold the field-level errors in place so the user can see exactly what needs fixing.

Submit buttons that don't tell you what submit does

"Submit" is the worst possible label for a submit button. It describes the action of the form, not the outcome for the user. Every form has a more specific label available: "Create account," "Place order," "Send message," "Save changes."

The label on the primary button is the last thing the user reads before committing to the action. It's worth making that label as clear as possible about what's about to happen. "Save changes" confirms the user is saving. "Place order" confirms they're committing to a purchase. "Submit" confirms nothing except that the form will be submitted, which the user already knew.

This also matters for trust. A checkout button labeled "Place order" is clearer about the implication (payment is about to happen) than one labeled "Submit" or, worse, "Continue."


The reason these patterns persist is that they're set up as defaults in component libraries that get copied, shipped, and inherited. The form looks complete. It validates. It submits. It passes QA. The drop-off doesn't show up until you're looking at the funnel data weeks later, and by then the form design is already the baseline that nobody wants to revisit.

Greg Sargent
Greg SargentDirector of Design Systems, Spring Health

I write about design systems, accessibility, and the way AI is changing how we build software.

Published January 21, 2026

Be the first to rate this article.