Mobile Form Validation UX
Most form validation is designed on a laptop and used on a phone. On a phone, half the screen is covered by a virtual keyboard, the error message that looked fine below the field is hidden behind it, the browser’s native validation bubble appears somewhere off-screen, the wrong keyboard makes typing a card number a chore, autocorrect rewrites email addresses, and a 16-pixel “×” to dismiss an error is too small to tap. None of these are validation rules — the rules are the same on every device — but together they decide whether mobile users can find and fix their mistakes. This topic covers the mobile-specific layer of validation UX: choosing keyboards and Enter-key hints that prevent errors, keeping errors visible while the keyboard is open, placing messages where thumbs and eyes can reach them, and timing feedback for touch. It keeps the site’s canonical <form novalidate> plus reportValidity() flow from the Constraint Validation API, because the native focus and scroll behaviour is a good starting point that just needs help on small screens.
The pain point is the most common mobile support complaint about forms: “I pressed Submit and nothing happened.” Usually something did happen — an error appeared — out of sight. Fixing that does not need a separate mobile validation system; it needs the same rules and messages delivered with three extra concerns in mind: what the keyboard covers, what a thumb can reach, and how much typing each field demands.
Prerequisites for Mobile Validation UX
| Requirement | Minimum version | Why it is needed |
|---|---|---|
inputmode, enterkeyhint |
iOS Safari 13+, Chrome Android 66+ | Choosing the right virtual keyboard and Enter key |
autocomplete tokens |
All mobile browsers | Autofill from saved profiles, SMS one-time codes |
visualViewport API |
iOS Safari 13+, Chrome Android 61+ | Knowing where the keyboard is |
interactive-widget viewport meta |
Chrome Android 108+ | Choosing whether the keyboard resizes the layout |
scrollIntoView({ block: "center" }) |
All | Bringing an invalid field into view |
| Real devices for testing | iOS and Android | Emulators misrepresent keyboards and autofill |
Mobile Input API Reference
| Attribute / API | Values | Effect on validation | Notes |
|---|---|---|---|
inputmode |
numeric, decimal, tel, email, url, search, none |
Right keyboard prevents invalid characters | Does not validate by itself |
enterkeyhint |
next, done, go, send, search |
Makes Enter’s action predictable | Pair with handling of Enter |
autocapitalize |
none, sentences, words |
Stops “Ada@example.com” style capitalisation | Set none on emails, usernames, codes |
autocorrect / spellcheck |
off / false |
Stops dictionary “fixes” to identifiers | Safari honours autocorrect |
autocomplete="one-time-code" |
token | Offers SMS codes above the keyboard | With inputmode="numeric" |
window.visualViewport |
height, offsetTop, resize event | Where the visible area is | Use to keep errors in view |
scrollIntoView |
options | Reveals the invalid field | Native reportValidity() scroll is not always enough |
Step-by-Step Implementation
1. Prevent errors with the right keyboard and text handling
<label for="email">Email address</label>
<input id="email" name="email" type="email" inputmode="email" autocomplete="email"
autocapitalize="none" autocorrect="off" spellcheck="false" enterkeyhint="next" required>
<label for="code">Verification code</label>
<input id="code" name="code" inputmode="numeric" autocomplete="one-time-code"
pattern="\d{6}" maxlength="6" enterkeyhint="done" required>
<label for="amount">Amount</label>
<input id="amount" name="amount" inputmode="decimal" enterkeyhint="go" required>
The right keyboard is validation you never have to report: a numeric keypad makes letters in a card number impossible, an email keyboard puts “@” and “.” within reach, and autocapitalize="none" stops the first letter of an email being capitalised. The full attribute guide is choosing inputmode and enterkeyhint.
2. Validate on blur, not per keystroke
Touch typing is slower and more error-prone than typing on a keyboard, and per-keystroke errors on a phone are both distracting and hard to read because the keyboard hides part of the form. Give the first verdict on blur and clear errors live once shown — the timing model from validating on blur versus on input, which matters even more on mobile.
3. Keep the invalid field visible when submitting
const form = document.querySelector<HTMLFormElement>("#checkout")!;
form.addEventListener("submit", (event) => {
if (form.checkValidity()) return;
event.preventDefault();
const first = form.querySelector<HTMLElement>(":invalid")!;
// Centre the field so its label above and message below both have room,
// then focus without letting the browser scroll it back under the keyboard.
first.scrollIntoView({ block: "center", behavior: matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth" });
first.focus({ preventScroll: true });
form.reportValidity();
});
Native reportValidity() scrolls the first invalid field into view, but on mobile it often lands the field at the very bottom of the visible area — just above the keyboard — with its error message underneath it. Centring the field first gives the label and message room. The keyboard-aware version, using visualViewport, is in validating forms with the virtual keyboard open.
4. Place messages where they survive the keyboard
A message above the input, between the label and the field, remains visible when the keyboard is open and the field is focused near the bottom of the viewport; a message below the field is the first thing the keyboard covers. Many mobile-first design systems place errors between label and input for exactly this reason. Tap targets for anything interactive in an error — “Did you mean …?”, “Remove file” — should be at least 44 by 44 CSS pixels. Placement options are compared in touch-friendly error message placement.
State Management and Edge Cases
Mobile adds states the desktop never sees: the keyboard can be open or closed, the viewport can resize or overlay, the page can be backgrounded mid-typing, and autofill or SMS codes can fill fields without keystrokes.
- Keyboard open, error appears below. Detect it with
visualViewportand scroll just enough to reveal the message. - Viewport resizes on keyboard open. On Android Chrome the layout viewport may shrink (depending on the
interactive-widgetsetting) while on iOS the keyboard overlays it; do not assume either. - Tab backgrounded during submit. Mobile browsers freeze background tabs; a submission in flight may resume later. Keep the double-submit guard from preventing double form submission.
- Switching apps to find information. Users leave the browser to copy a code or an account number and return; the page may have been reloaded. Preserve drafts so a returning user does not face an empty form and a fresh set of required-field errors.
- One-time codes arriving by SMS. The code is inserted in one
inputevent; auto-submit after validating, but never assume the value was typed digit by digit.
Accessibility Compliance on Mobile
Mobile screen readers — VoiceOver on iOS and TalkBack on Android — navigate by swipe rather than Tab, which changes how errors are found. The same fundamentals apply, but some matter more. 3.3.1 Error Identification: errors must be text linked to the field with aria-describedby, because swipe navigation reads the description when the field is reached. 2.5.8 Target Size (Minimum) in WCAG 2.2 requires targets of at least 24 by 24 CSS pixels (44 is the platform guideline) — relevant to error dismiss buttons, “show password” toggles and inline suggestions. 1.3.5 Identify Input Purpose makes autofill tokens a requirement, and on mobile they are the single biggest error-prevention tool. 4.1.3 Status Messages covers form-level results; on mobile a toast that disappears after three seconds is often gone before a TalkBack user reaches it, so prefer persistent inline status.
Focus management needs a mobile check too: moving focus to an invalid field opens the keyboard, which is usually what the user wants — but moving focus to an error summary at the top of a long form does not open the keyboard, which gives the user a calm overview first. Both are reasonable; test which serves your forms better on real devices.
Common Gotchas and Debugging
type="number" for codes and cards. It shows spinners, drops leading zeros and, on some keyboards, lacks a clear “done”. Use type="text" with inputmode="numeric".
<!-- Before -->
<input type="number" name="code">
<!-- After -->
<input type="text" inputmode="numeric" autocomplete="one-time-code" pattern="\d{6}" name="code">
Autocorrect on emails and usernames. iOS may turn “ada.lovelace” into “Ada.lovelace” or a dictionary word. Set autocapitalize="none", autocorrect="off" and spellcheck="false".
Relying on the native bubble. On mobile, the browser’s validation bubble can appear off-screen or disappear as the keyboard opens. Always render inline messages; treat the bubble as a bonus.
Sticky footers covering fields. A fixed “Continue” bar plus an open keyboard can leave almost no visible form. Hide or un-stick the bar while an input is focused, or account for it when scrolling fields into view.
Hover-only hints. Tooltips that explain a rule on hover do not exist on touch devices. Put hints in visible text.
Blocking paste into confirmation fields. Mobile users paste far more than desktop users, because typing is slow. Blocking paste into “confirm email” or password fields forces error-prone retyping and fails WCAG 3.3.8 for authentication fields; remove the block.
Testing Mobile Validation on Real Devices
Device emulation in desktop browsers is useful for layout but misleading for everything this topic is about: the emulated keyboard does not occupy the screen, autofill behaves differently, and SMS code suggestions never appear. Keep a short manual test script for real iOS and Android devices — fill the form with autofill, submit it empty, fix each error with the keyboard open, receive a one-time code — and run it for every significant form change. Automate what can be automated: Playwright’s mobile device descriptors check layouts at small widths and can simulate a shrunken visual viewport, and an overflow check at 320 pixels wide catches the long unbreakable error messages that push layouts sideways. The broader browser-test approach is in testing form error messages with Playwright.
import { test, expect, devices } from "@playwright/test";
test.use({ ...devices["iPhone 13"] });
test("first error is centred in the viewport after submit", async ({ page }) => {
await page.goto("/checkout");
await page.getByRole("button", { name: "Continue" }).click();
const box = await page.getByLabel("Email address").boundingBox();
const vh = page.viewportSize()!.height;
expect(box!.y).toBeGreaterThan(vh * 0.2);
expect(box!.y).toBeLessThan(vh * 0.7);
});
Enter Key Behaviour Across a Mobile Form
On a phone, the Enter key is the main navigation control: users tap it to move to the next field far more often than they reach up to tap the next input. By default, Enter in a single-line input submits the form, which on mobile means submitting after the first field — and a burst of validation errors for every field not yet filled. Make Enter predictable instead. Label it with enterkeyhint="next" on every field except the last, move focus to the next field when it is pressed, and let only the last field’s Enter (labelled done or go) submit through the canonical requestSubmit() path, which runs your validation. The label and the behaviour must agree: a key that says “next” but submits is worse than the default.
form.addEventListener("keydown", (event) => {
if (event.key !== "Enter" || !(event.target instanceof HTMLInputElement)) return;
const fields = [...form.querySelectorAll<HTMLInputElement>("input:not([type=hidden]):not([disabled])")];
const i = fields.indexOf(event.target);
if (i >= 0 && i < fields.length - 1) {
event.preventDefault();
fields[i + 1].focus(); // "next": move on, validation of this field happens on blur
}
// On the last field, Enter falls through and submits via the normal submit handler.
});
Error Summaries on Small Screens
An error summary at the top of a long mobile form is valuable — it tells the user how many problems there are — but it can also push the first field below the fold, so the user scrolls past the summary to find it. Keep mobile summaries short: a heading with the count and one line per error, each a link that scrolls its field to the centre of the viewport and focuses it. Do not repeat the full message text if it is long; the inline message will be visible once the user arrives. When there is only one error, skip the summary and take the user straight to the field. The component itself is described in building an accessible error summary; on mobile, the only changes are brevity and centring.
Orientation, Zoom and Text Size
Mobile users rotate phones, zoom forms and set large system text, and each changes how validation UI fits. In landscape, the keyboard can cover almost the entire viewport, leaving room for barely one field — which makes the “message above the input” placement even more valuable. Pinch zoom must never be disabled (maximum-scale=1 fails WCAG 1.4.4 Resize Text), and inputs should use at least a 16-pixel font size so iOS does not auto-zoom on focus, which otherwise shifts the error out of view. With large system text, long error messages wrap onto several lines; reserve space generously and never truncate an error with an ellipsis — the text is the instruction. WCAG 1.4.10 Reflow asks that the form work at 320 CSS pixels wide without horizontal scrolling, which is also where long unbroken email addresses inside error messages cause trouble; allow them to wrap with overflow-wrap: anywhere.
Performance on Low-End Phones
Validation code that feels instant on a laptop can make typing lag on an entry-level phone, and input lag reads to users as a broken form. Keep per-keystroke work tiny: no schema parsing of the whole form on every input event, no synchronous layout reads in input handlers, no large dependencies (phone metadata, strength dictionaries) loaded until the field that needs them is focused. Measure Interaction to Next Paint on a real low-end device or with CPU throttling; a validation handler that pushes INP above 200 milliseconds is worth optimising before any visual polish.
Reducing Typing to Reduce Errors
The most effective mobile validation is asking for less typing. Offer autofill with correct tokens; use native pickers for dates close to today; use segmented choices instead of typed answers where the options are few; look up addresses from a postcode; accept pasted content and normalise it; and pre-fill anything you already know. Each of these removes a class of errors before a validation rule is needed. When typing is unavoidable, show the expected format as a visible example next to the label — “For example, 07700 900123” — because mobile users cannot hover for help and are less likely to guess a format correctly on a small keyboard. The input-type-specific patterns for phones, addresses and cards are in the validating common input types section.
Browser Compatibility Matrix
| Feature | iOS Safari | Chrome Android | Samsung Internet | Notes |
|---|---|---|---|---|
inputmode |
12.2+ | 66+ | 9.2+ | — |
enterkeyhint |
13.4+ | 77+ | 12+ | — |
autocomplete="one-time-code" |
12+ | Via WebOTP / keyboard | Varies | Android also offers WebOTP API |
visualViewport |
13+ | 61+ | 8+ | — |
interactive-widget=resizes-content |
Ignored | 108+ | 21+ | Controls layout resize with keyboard |
Frequently Asked Questions
Why do users say nothing happens when they submit on mobile?
Usually an error appeared out of sight — below a field hidden by the keyboard, or in a native bubble off-screen. Scroll the first invalid field to the centre of the viewport, render inline messages, and consider placing errors above inputs on mobile.
Should mobile forms validate on every keystroke?
Generally no. Give the first verdict when the user leaves a field and clear errors live once shown. Per-keystroke errors are distracting on small screens and often hidden by the keyboard.
Which attributes prevent the most mobile form errors?
Correct autocomplete tokens, inputmode for the right keyboard, and autocapitalize="none" with autocorrect off and spellcheck="false" on emails, usernames and codes.
How large should error-related buttons be on mobile?
WCAG 2.2 requires at least 24 by 24 CSS pixels for targets; platform guidelines recommend about 44 by 44 for comfortable touch. This includes dismiss buttons, suggestions and visibility toggles.
Related Guides
- Choosing inputmode and enterkeyhint — keyboards that prevent errors.
- Validating Forms with the Virtual Keyboard Open — keeping errors visible.
- Touch-Friendly Error Message Placement — where messages survive the keyboard.
- Best Practices for Inline Validation Timing — timing that suits touch.
← Back to UX Patterns & Error State Design