Form UX Best Practices: Validation, Progress Bars and Autofill
A good form is one people barely notice. The browser fills in what it already knows, mistakes are flagged while they’re easy to fix, and long forms tell you how far you’ve got. This guide goes through the details that make that happen: validation timing, error messages, progress indicators and autofill, based on Google’s web.dev guidance and the W3C’s Web Accessibility Initiative (WAI) forms tutorials.
Updated

Start with plain, well-structured HTML
Almost every best practice in this guide depends on the form being built from standard elements. web.dev’s sign-in form guidance says to use a real form element rather than a div with a script attached, because a plain form makes the page accessible to screen readers and other assistive devices. Browsers, password managers and autofill all rely on the same structure.
| Element | Why it matters | Guidance |
|---|---|---|
| <form> | Lets the Enter key submit, and lets browsers and assistive tech recognize the form | Use a separate form for each task on a page (sign-in and search are two forms) |
| <label> | Gives each field a name that screen readers announce and a larger click target | Connect it with for and id; W3C notes the for value must exactly match the control’s id |
| <button> | Submits the form natively | Give extra buttons (like a show-password toggle) type="button" so they don’t submit |
| Stable name and id | Autofill and password managers use them to recognize fields | web.dev advises keeping them unchanged between page loads and deployments |
Where labels sit matters too. web.dev suggests putting labels above inputs, which works on narrow phone screens and keeps the label in view while typing. The W3C labels tutorial notes the convention for radio buttons and checkboxes: the label goes to the right of the control. And because most users prefer or even need visible labels, the W3C says a label should only be hidden visually when the purpose is obvious from context, such as a search box next to a search button, and even then it must still exist in the code.
Make autofill work for you
Autofill is the fastest way to shorten a form without removing a single question. Browsers can fill names, emails, phone numbers and addresses in one tap, but only if each field says what it is. That’s the job of the autocomplete attribute. MDN’s reference lists the full set of values; these are the ones most forms need.
| Field | Input type | autocomplete value |
|---|---|---|
| Full name | text | name |
| email (or username on a sign-in form) | ||
| Phone | tel | tel |
| Street address (one box) | textarea | street-address |
| Address lines | text | address-line1, address-line2 |
| ZIP or postal code | text | postal-code |
| Country | select or text | country |
| Existing password | password | current-password |
| New password | password | new-password |
| One-time code from SMS | text | one-time-code |
| Card number | text with inputmode="numeric" | cc-number |
A few rules from web.dev make these values work better. When a page has both a shipping and a billing address, prefix the values (for example, autocomplete="shipping postal-code" and "billing postal-code") so the browser fills the right one. Use a single name field with autocomplete="name" unless you have a clear reason to split it. And avoid custom widgets for things like card expiry dates, because they can break autofill.
Choose the right input type and keyboard
The input type controls which keyboard appears on a phone and what the browser can check for you. Getting it wrong is one of the most common mobile annoyances.
| Data | Use | Avoid |
|---|---|---|
| Email address | type="email" (email keyboard, built-in format check) | type="text" |
| Phone number | type="tel" (phone keypad) | type="number", which adds up/down arrows that make no sense for phone numbers |
| Card number, ZIP code, numeric IDs | type="text" with inputmode="numeric" | type="number"; web.dev specifically advises against it for card numbers |
| Website URL | type="url" | type="text" |
| Dates | type="date", or a text field with a clear format hint | Custom date widgets; web.dev warns they can break autofill for card expiry dates |
web.dev’s payment and address guidance adds a small but useful touch: the enterkeyhint attribute changes the label on a phone’s Enter key, so it can say “next” on the first fields and “done” on the last.
Validation: when to check, and how
web.dev’s rule is short: validate data during entry, not just on form submission. The question is when “during entry” should be. The W3C notifications tutorial describes two options, and each suits different fields.
| Timing | Best for | Watch out for |
|---|---|---|
| While typing (keypress) | Instant checks that help, like whether a username is available or a password meets the rules | Showing “invalid” before the visitor has finished typing |
| When the field loses focus (blur) | Formatted data like dates, emails and phone numbers | Nothing major; this is the safest default |
| On submit | Final check of everything, plus server-side checks | Using it as the only check; finding five errors at once is discouraging |
For formatted data, the W3C points out why blur is better: checking a date while it’s being typed would show an error most of the time. For screen reader users, the W3C examples announce messages through live regions: polite for keypress feedback, so the message is read when the user pauses, and assertive for blur feedback.
Two more rules apply whatever the timing. First, client-side validation is for the visitor’s convenience, not for security. The W3C validation tutorial says data needs to be validated on the server side as well, and web.dev agrees that you must always validate and sanitize on the backend. Second, accept the formats people naturally use. The W3C recommends accepting multiple notations rather than forcing one strict format. A phone number with spaces, dashes or brackets is still a phone number.
Don’t disable the submit button
A grayed-out submit button that only lights up once everything is valid looks tidy, but it hides the problem. The visitor can see that something is wrong without being told what. Both web.dev guides advise against disabling the button while input is incomplete; let people press it, then explain exactly what’s missing. The one exception web.dev mentions is disabling the button after the first click, to prevent duplicate submissions.
Writing error messages people can act on
An error message has one job: tell the visitor what to do next. The W3C notifications tutorial recommends pairing text messages with visual cues next to each control, and making the message explain how to fix the problem, not just that one exists. web.dev’s payment guidance puts the tone well: don’t “tell off” users; help them fix problems as they happen.
| Unhelpful | Helpful |
|---|---|
| Invalid input | Enter an email address like name@example.com |
| Error in field 4 | Enter your phone number, including the area code |
| Required | Tell us your company name so we can prepare a quote |
| Wrong format | Enter the date as MM/DD/YYYY |
| Password not accepted | Use at least 12 characters |
- Put it next to the field. The message should sit directly below or beside the field it’s about, not in a banner at the top only.
- Don’t rely on color alone. A red border is invisible to some visitors. Pair it with text and, if you like, an icon.
- Connect it in the code. The W3C tutorial links each field to its error message with aria-describedby so assistive technology reads the message with the field.
- Clear it as soon as it’s fixed. A message that lingers after the visitor corrects the field makes them doubt the fix.
- Keep what they typed. Never clear the field when showing an error; let people edit their entry instead of retyping it.
After a failed submit: summary, focus and scroll
When someone presses submit and something is still wrong, three things help them recover quickly. The W3C tutorial suggests listing the errors above the form under a clear heading, with each item naming the field, describing the problem and linking to the control. It also recommends moving focus to the first field that contains an error. On a long form, that same move scrolls the visitor straight to the problem instead of leaving them to hunt for it.
The page title can help too. The W3C suggests updating the title to report errors (its example is “3 Errors – Billing Address”), because screen reader users hear the title as soon as the page loads, even when the main heading is far down the page.
Marking required and optional fields
Visitors shouldn’t have to submit a form to find out which fields are required. The W3C validation tutorial recommends three layers: the required attribute so browsers and assistive technology know, a visible indicator in the label (its example uses the text “(required)”), and aria-required for older combinations of browser and screen reader.
Which side should you mark? If most fields are required, marking the few optional ones is less noisy. If it’s a mix, mark both. What matters is consistency and a text label: an asterisk alone needs a legend explaining it, and is easy to miss. Be cautious about making fields required at all. web.dev’s address guidance specifically warns against requiring a house number and street name in separate inputs, and suggests caution with required address fields in general.
Progress indicators for long forms
A short form doesn’t need a progress bar. A long application, quote request or multi-step checkout often does, because the most discouraging thing about a long form is not knowing how long it is. The W3C multi-page forms tutorial describes several ways to show progress.
| Method | Example | When to use it |
|---|---|---|
| In the page title | “Step 2 of 4: Shipping Address” | Always on multi-step forms; screen reader users hear it first |
| In the main heading | “Shipping Address (Step 2 of 4)” | Helps visitors scanning the page |
| Step list (ordered list) | Account → Details → Review → Done | Fixed number of steps; lets people see what’s coming and go back |
| HTML progress element | A bar that fills as you go | When the number of steps depends on earlier answers |
How you split the form matters as much as how you display progress. The W3C recommends dividing a long form into logical groups, the way shops separate shipping from payment, and making optional steps easy to recognize and skip. When visitors can go back to earlier steps, it says any data already entered in the current step should be saved. And it recommends a review step with links to completed steps before the final submit. web.dev’s checkout guidance also recommends showing progress through clear steps.
A progress bar that measures fields completed rather than pages works well on single-page forms too. Counting only required fields keeps it honest: the bar reaches 100% when the form can actually be sent.
Buttons, touch targets and text size
- Say what the button does. web.dev’s examples: “Create account” or “Sign in,” not “Submit” or “Start”; and in checkout, “Proceed to Payment” rather than “Continue.”
- Make targets big enough. web.dev cites Apple’s 48 × 48 pixel guidance and the W3C’s suggestion of at least 44 × 44 CSS pixels, and recommends around 15px of padding on inputs and buttons on mobile, about 10px on desktop.
- Use readable text. web.dev suggests about 20px is right for form text on mobile, tested with users who have low vision.
- Give inputs visible borders. web.dev recommends #ccc or darker on a white background, so fields don’t disappear into the page.
- Keep the first fields above the keyboard. On mobile, web.dev suggests keeping the key fields and the button near the top so the on-screen keyboard doesn’t cover them.
Ask less, and never twice
web.dev’s address guidance says “Don’t ask for data you don’t need,” and its sign-in guidance warns against asking people to enter their email or password twice. Retyping adds work for everyone and raises abandonment. Instead of a second password field, web.dev suggests a “Show password” toggle so people can check what they typed. For email addresses, a review screen before sending gives people the same chance to spot a typo. Our form abandonment guide covers trimming fields in more detail.
Protect work in progress
Long forms get interrupted. Two aids help people avoid starting over. A warning before leaving a partly filled form catches accidental tab closes. Saving entries in the browser as people type lets them return and pick up where they left off. Use the leave warning only when there’s actual unsent input, and never for a form someone hasn’t touched.
Confirm success clearly
The last screen is part of the form. The W3C notifications tutorial stresses that success messages are important to confirm task completion, using the main heading or the page title, for example “Thank you for submitting your order.” Say what happens next: when they’ll hear back, whether an email is on its way, and what to do if it doesn’t arrive.
Test like your visitors do
web.dev notes that form behavior varies significantly across platforms, so test on the browsers and devices your visitors actually use, and check that buttons aren’t hidden on small screens. Then measure in the field: page analytics, interaction analytics (funnels and events per field) and real-user performance data. A quick hands-on test catches most problems.
- Fill in the form on your own phone using only autofill. Note every field it skips.
- Submit it empty. Check that every error says what to do and that the page scrolls to the first one.
- Enter a phone number with spaces and dashes. It should be accepted.
- Tab through the form with a keyboard only. Every field and button should be reachable in a sensible order.
- Start filling it in, then close the tab. Check what happens when you come back.
- Read the success screen as a new visitor. Is it clear what happens next?
Form UX checklist
| Area | Check |
|---|---|
| Structure | Real form, label and button elements; labels above inputs; stable name and id |
| Autofill | autocomplete on every field it applies to; shipping and billing prefixes where both appear |
| Keyboards | email, tel and url types; inputmode="numeric" for numeric codes |
| Validation | On blur for formatted fields; on submit as a final check; always on the server too |
| Errors | Next to the field, in text, with a fix; focus and scroll to the first error on submit |
| Required | Marked in text before submit; as few as possible |
| Progress | Step count in title and heading for multi-step; progress bar for long single pages |
| Buttons | Specific labels; never disabled while incomplete; large enough to tap |
| Interruptions | Leave warning for unsent input; saved entries for long forms |
| Success | Clear confirmation and what happens next |
Form UX aids in marketingLABO
marketingLABO’s form builder has an EFO (form experience optimization) settings tab with input aids you can turn on per form. Each maps to a practice above.
| Setting | What it does | Related practice |
|---|---|---|
| Real-time validation | Shows errors as soon as a field loses focus | Validate on blur |
| Highlight empty required fields | Visually marks required fields that are still empty | Marking required fields |
| Scroll to the first error on submit | Brings the first problem into view | Recovering after a failed submit |
| Progress bar | Shows progress based on required fields completed | Progress for long forms |
| Confirmation screen | Shows a review screen after the submit button is clicked, before sending | Review step |
| Warn before leaving | Warns visitors before they leave a partly filled form | Protect work in progress |
| Auto-save entries | Saves entries in the visitor’s browser | Protect work in progress |
In the field settings, you can add help text and placeholders, edit the error messages, show “Required” and “Optional” badges, choose whether labels sit above or beside inputs separately for desktop and mobile, and insert step breaks to split a long form into steps. Email fields use the email input type and phone fields the telephone type, so phones show the matching keyboard. Email fields can also show a second confirmation field; given web.dev’s advice against double inputs, we’d suggest leaving it off and relying on the confirmation screen instead.
While you build, the EFO score checks your field count (seven or fewer recommended), your required fields (five or fewer) and whether free-text questions sit near the end. Once the form is live, the drop-off report shows where people stop, and a form A/B test lets you check whether a UX change actually raised the conversion rate.
Forms with drop-off tracking are included on every plan; see plans and pricing for form limits. Related reading: form abandonment for finding the field where people give up, and website heatmaps for seeing whether visitors even reach your form.
FAQ
Should I validate as people type or when they leave a field?
For most fields, when they leave it. Checking while typing works for instant helpful feedback, like password rules, but on formatted fields it shows errors before the visitor has finished.
Are placeholders a good replacement for labels?
No. web.dev says not to use placeholders as input labels, because the text disappears once typing starts. Use a visible label and keep placeholders for examples.
Does every form need a progress bar?
No. A five-field contact form is short enough that a progress bar adds clutter. Use one for long single-page forms and step indicators for multi-step forms.
Should I split first and last name?
Only if you have a clear reason. web.dev recommends a single name field with autocomplete="name", which works for more naming conventions and fills in one tap.
Is a confirmation screen worth the extra click?
For forms where mistakes are costly, such as quotes, bookings or applications, often yes, because it catches typos before sending. For a newsletter sign-up, it’s usually an unnecessary step. If unsure, A/B test it.
Want to apply these to your own forms? Sign up free and build a form with real-time validation, a progress bar and drop-off tracking.
Sources
- web.dev: Sign-in form best practices
- web.dev: Payment and address form best practices
- web.dev Learn Forms: Help users avoid re-entering data in forms (autofill)
- MDN Web Docs: HTML attribute autocomplete
- W3C WAI Forms Tutorial: Labeling Controls
- W3C WAI Forms Tutorial: Validating Input
- W3C WAI Forms Tutorial: User Notifications
- W3C WAI Forms Tutorial: Multi-page Forms
Start free — no credit card needed
Sign up freeMore articles

How to Read a Single Visitor's Journey Through Your Site
Use a per-visitor timeline to spot loops, hesitation and return visits, tell anonymous from known contacts, and avoid reading too much into one journey.
Read the article →
How to Target Returning Visitors with Different Messages Than First-Timers
Show first-time and returning visitors different messages using visit frequency and days since the last visit, with recipes and the limits of tracking.
Read the article →
UTM Parameters Explained (and How to Match Landing Messages to Your Ads)
What each UTM parameter means, a naming convention that keeps reports clean, common tagging mistakes, and how to show visitors a message that matches the ad.
Read the article →
Micro-Conversions: The Small Signals That Predict a Sale
What micro-conversions are, four practical ones to track (pages viewed, key URLs, time on site, return visits), how to set thresholds and how to act on them.
Read the article →
Are Email Open Rates Still Reliable After Apple Mail Privacy Protection?
How Apple Mail Privacy Protection inflates email open rates, what opens can still tell you, and why clicks and site returns make better signals.
Read the article →
SPF, DKIM and DMARC Explained for Small Store Owners
What SPF, DKIM and DMARC do, how they work together, what Gmail and Yahoo require of senders, and how to set them up with your email provider.
Read the article →