Anticode Open builder

Web form design best practices: labels, one column, right inputs, useful errors

Most form problems are solved by four habits: a visible label above every field, a single column, the input type that matches the data, and error messages that say exactly how to fix the problem. Get those right and a form feels short even when it isn't.

Updated · By the Anticode team

Labels: visible, above, and never only a placeholder

The first of the web form design best practices is the simplest: every field needs a label that stays on screen while someone types. Placeholder text inside the field disappears on the first keystroke, is usually too faint to pass contrast, and leaves people who return to a half-finished form guessing what each box was for. Put the label above the field, where it's read just before the input and doesn't fight for horizontal space on phones. Associate it in the markup (label for matching the input's id, or the input inside the label) so screen readers announce it and clicking the label focuses the field.

Placeholders can still help with format examples, such as “e.g. 07700 900123”, but a hint below the label is more reliable, because it doesn't vanish.

Layout: one column, grouped, in a sensible order

  • One column. The eye moves straight down; nobody misses a field on the right. The common exception is genuinely paired short fields, like a date and a time, side by side on wide screens.
  • Group related fields with fieldset and legend: “Your details”, “The job”, “When”. Radio buttons and checkbox sets always belong in a fieldset, so the question is read with each option.
  • Order fields as people think. Name before email, the problem before the date, the address in the order the country writes it.
  • Size inputs to their content. A postcode field doesn't need to be as wide as a message box; widths hint at what's expected.
  • One primary button at the end, aligned with the fields, with a label that says what happens.

The right input for each kind of data

Input types and attributes that save typing
DataMarkupWhy
Emailtype="email" autocomplete="email"Email keyboard on phones, browser autofill
Phonetype="tel" autocomplete="tel"Number pad; doesn't force a format
Whole numbersinputmode="numeric"Number pad without the quirks of type=number
Datetype="date" or three fields for birth datesNative picker for near dates; typing is faster for distant ones
A choice of 2 to 5Radio buttonsAll options visible at once
A choice of manyA select, or a searchable listSaves space; harder to scan
Long texttextarea with a character limitRoom to write, and a clear ceiling

Set text inputs to at least 16px to stop iOS Safari zooming in on focus, and make fields at least 44px tall. Use autocomplete values wherever they apply; WCAG asks for them on fields that collect information about the user.

Validation: when it runs

Validating as someone types tells them they're wrong before they've finished. Validating only on submit makes them hunt. The middle path works best: check a field when the person leaves it, and recheck as they correct it. CSS can help: the :user-invalid pseudo-class applies only after the user has interacted with a field, unlike :invalid, which can paint an empty form red on load. On submit, if there are errors, move focus to a summary at the top or to the first invalid field.

Error messages that fix the problem

Rewriting unhelpful error messages
UnhelpfulHelpful
Invalid inputEnter an email address with an @, like name@domain.co.uk
Field requiredEnter your phone number so we can confirm the booking
ErrorChoose a date from tomorrow onwards
Password does not meet requirementsUse at least 12 characters

Put the message next to the field, in text, connected with aria-describedby so it's read with the field. Don't rely on a red border alone: some people can't see the colour change, and it says nothing about what's wrong. Never clear what someone typed because one field failed. There's more on wording in form error messages.

Forms in Anticode

Anticode's forms follow most of these rules by default: labels above fields, one column on phones, fields typed for their data, text at 16px, and invalid fields marked only after interaction. Before publishing, Sentinel fails the page if any field has no label, and also checks that text fields have a type and a length limit and that every form posts to the site's own address. Contact, booking and newsletter forms send to Anticode's form pipeline, where submissions are saved and sealed at rest.

Booking forms group time slots as radio buttons in a fieldset with a legend. For the contact form specifically, which fields to ask for and what to say next to it, see contact form design.

Questions people ask

Can placeholder text replace labels?

No. Placeholders disappear when typing starts and are often too faint to read. Use a visible label and, if needed, a hint below it.

Should labels go above or beside fields?

Above, for most web forms. It's faster to scan, works at every screen width and keeps the label close to the field on phones.

When should form validation run?

When the person leaves a field, and again as they fix it. Avoid flagging errors while they're still typing or before they've touched the form.

Sources

  1. Understanding WCAG 2.2: Identify Input Purpose, checked