skip to content

Forms and Inputs

The only part of HTML with real built-in behavior: controls, labels, native validation, submission, and autofill. Interviewers ask about forms because most bugs and accessibility failures in real apps come from reimplementing what the platform already does.

part ofHTMLoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

The HTML autocomplete attribute accepts more than "on" and "off". What is its token vocabulary, and what would you put on the name, email and address inputs of a checkout form?

level: juniorimportance: must knowfreq 65%

answer

  1. not a boolean
  2. a fixed list of field names
  3. given-name, street-address, postal-code
  4. "on" only permits, it does not describe
  5. WCAG 1.3.5 Identify Input Purpose

basics

~20 s

autocomplete takes a defined vocabulary of field-name tokens — name, email, tel, street-address, address-level2, postal-code, country, cc-number — not just on/off. The token tells the browser what a field means so autofill fills it correctly.

solid answer

~40 s

`autocomplete` is not a boolean. HTML defines a fixed vocabulary of autofill field names, and the value you write names what the field collects: `name` (or `given-name` / `family-name`), `email`, `tel`, `organization`, `street-address` or `address-line1` / `address-line2`, `address-level2` for the city, `address-level1` for the state or region, `postal-code`, `country-name`, and the payment set `cc-name`, `cc-number`, `cc-exp`, `cc-csc`. Writing `autocomplete="on"` only permits autofill — the browser still has to guess the meaning from the `name`, `id`, `label` and placeholder text, which is exactly what breaks on design-system markup with generated ids or non-English labels. A token removes the guess. It is also how you satisfy WCAG 2.1 success criterion 1.3.5, Identify Input Purpose, which requires the purpose of inputs collecting the user's own data to be programmatically determinable.

code

html · 21 lines
html
<form method="post" action="/checkout">
  <label for="fn">First name</label>
  <input id="fn" name="fn" autocomplete="given-name">

  <label for="ln">Last name</label>
  <input id="ln" name="ln" autocomplete="family-name">

  <label for="em">Email</label>
  <input id="em" name="em" type="email" autocomplete="email">

  <label for="st">Street address</label>
  <input id="st" name="st" autocomplete="street-address">

  <label for="ct">City</label>
  <input id="ct" name="ct" autocomplete="address-level2">

  <label for="pc">Postal code</label>
  <input id="pc" name="pc" autocomplete="postal-code">

  <button>Continue</button>
</form>

go deeper

for a junior

Know that autocomplete takes named tokens and be able to say a handful from memory — given-name, family-name, email, tel, street-address, postal-code, cc-number — and put them on a form without inventing spellings.

for a middle

Explain what the browser does when the token is absent: heuristics over name, id, label and placeholder that fail on generated ids and non-English labels. Be clear that "on" permits autofill but describes nothing.

for a senior

Show you treat autofill correctness as a product metric on checkout and sign-up flows, and that you audit a design system's input component so the token is a first-class prop rather than something each team remembers to pass.

for a principal

Own the tradeoff between a component library that hides markup and the per-field metadata autofill needs. Decide where the tokens live, how they are reviewed, and how you tie WCAG 1.3.5 conformance to that same mechanism instead of a separate checklist.

## The attribute is a vocabulary, not a switch Most people first meet `autocomplete` as `autocomplete="off"`, which makes it look like a boolean toggle. It is not. The HTML standard defines a closed list of **autofill field names** — tokens such as `name`, `email`, `street-address`, `postal-code`, `cc-number` — and the value of the attribute is drawn from that list. The token is a machine-readable statement of *what this field is for*, addressed to the browser and to any password manager or assistive technology reading the form. The attribute is valid on `<input>` (for the text-like types), `<textarea>`, `<select>`, and on `<form>` itself, where it sets the default for the controls inside it. ## The token grammar A full value has up to four parts, in a fixed order: ``` [section-*] [shipping|billing] [home|work|mobile|fax|pager] field-name ``` Only the field name is required, so the everyday case is a single token. The optional pieces group fields: `shipping street-address` and `billing street-address` describe two different addresses in one form, and a `section-*` prefix creates an arbitrary named group when you have two of the same kind of thing on one page. ## The tokens you actually use Identity and contact: `name`, or the split forms `given-name`, `family-name`, `additional-name`, `honorific-prefix`; `nickname`, `username`, `organization`, `organization-title`, `email`, `tel`, `url`, `bday`. Address: `street-address` for a single multi-line field, or `address-line1` / `address-line2` / `address-line3` when it is split; `address-level2` for the city or town, `address-level1` for the state, province or region; `postal-code`; `country` for the two-letter code and `country-name` for the human-readable name. Payment: `cc-name`, `cc-number`, `cc-exp` (or `cc-exp-month` and `cc-exp-year`), `cc-csc`, `cc-type`. Credentials and codes: `username`, `current-password`, `new-password`, `one-time-code`. A typical checkout block looks like this: ```html <label for="fname">First name</label> <input id="fname" name="fname" autocomplete="given-name"> <label for="email">Email</label> <input id="email" name="email" type="email" autocomplete="email"> <label for="addr">Street address</label> <input id="addr" name="addr" autocomplete="street-address"> <label for="city">City</label> <input id="city" name="city" autocomplete="address-level2"> <label for="zip">Postal code</label> <input id="zip" name="zip" autocomplete="postal-code"> ``` ## What happens when you leave the token off The browser does not give up — it guesses. It runs heuristics over the control's `name` and `id`, the text of its label, its placeholder and its position among neighbouring fields. Those heuristics work well on conventional English markup (`name="email"`) and poorly everywhere else: framework-generated ids like `id="input-7a3f"`, class-name-driven markup, minified attribute names, labels in a language the heuristic was not tuned for, or a two-line address split in an unusual way. A guess that lands wrong is worse than no fill — the user's postcode ends up in the city field and they now have to clear it. Writing `autocomplete="on"` does not fix this. `on` only says "autofill is permitted here", which is already the default; the browser still has to work out the meaning. Only a field-name token communicates meaning. ## Why it is worth the attributes Three separate payoffs. First, completion speed: a checkout that fills in one tap has measurably less abandonment than one typed on a phone keyboard. Second, correctness: the browser stores structured profile data, so a correctly tokenised form gets the right subfield in the right box instead of a fuzzy match. Third, accessibility: WCAG 2.1 added success criterion 1.3.5, *Identify Input Purpose* (Level AA), which requires that the purpose of a field collecting information about the user be programmatically determinable. In HTML the way you satisfy it is precisely these tokens — they let assistive technology and personalisation tools relabel a field with a familiar word or icon for users who need that. ## Common mistakes Inventing tokens. `autocomplete="firstname"` or `autocomplete="zip"` are not in the vocabulary; an unrecognised token is treated as if you had written `on`, so you get the guessing behaviour back without noticing. Use `given-name` and `postal-code`. Confusing the token with the input type. `type` controls the keyboard, the built-in validation and the widget; `autocomplete` controls what value gets suggested. `type="email" autocomplete="email"` is normal and correct — they are answering different questions. Confusing it with `name`. The `name` attribute is what your server sees on submission; the autocomplete token is what the browser sees. They are independent, and you should not rename your form fields to make heuristics work when a token states it outright. Finally, remember the vocabulary is fixed and small. If nothing in it describes your field — an internal reference number, a free-text note — then the honest answer is that no token applies, and you simply omit the attribute.

  • If you write a token the browser does not recognise, such as autocomplete="zipcode", what happens?
    An unrecognised token is not an error you will see. The browser cannot map it to a known autofill field, so it falls back to treating the field as if autofill were simply enabled and resumes guessing from the `name`, `id` and label. The failure is silent, which is why invented tokens survive in codebases for years. Use the spec spelling — `postal-code`, not `zipcode`.
  • How does the autocomplete token relate to the input's type and name attributes?
    They are three independent channels. `type` decides the widget, the on-screen keyboard and the built-in validation. `name` is the key your server receives on submission. `autocomplete` describes the field's meaning to the browser's autofill store. `<input type="tel" name="contactPhone" autocomplete="tel">` sets all three deliberately, and none of them can substitute for another.
  • Can autocomplete be set on the form element rather than on every input?
    Yes, but only usefully as `autocomplete="on"` or `"off"`, which becomes the default state for the controls inside it. Field-name tokens are inherently per-field — the form does not know which of its inputs is the postcode. So a form-level value is a coarse switch, and the descriptive tokens still have to go on each control.

saying these in an interview costs you the question

  • Says autocomplete is just on or off
  • Invents tokens like firstname or zip
  • Claims autocomplete="on" tells the browser what the field means
  • Thinks the name attribute is what autofill reads
  • Confuses the autocomplete token with the input type

context

open as a page

In a plain HTML form, one input carries required and another carries pattern="[0-9]{4}". What exactly does the browser do when the user presses the submit button while those constraints are not satisfied?

level: juniorimportance: must knowfreq 76%

basics

~20 s

The browser blocks submission: no submit event fires and no request goes out. It focuses the first invalid control, shows a built-in message bubble beside it, and fires a non-bubbling invalid event on each failing control.

open as a page

What do you gain by setting an HTML <input> to type="email" instead of leaving it as type="text"?

level: juniorimportance: must knowfreq 70%

basics

~20 s

type="email" makes the browser reject values that are not shaped like an address, switches mobile keyboards to an @-and-dot layout, and helps password managers and autofill recognise the field. It never checks that the address exists.

open as a page

In an HTML form, what are the two ways to associate a <label> element with an input, and what does that association actually give the user?

level: juniorimportance: must knowfreq 80%

basics

~20 s

Two ways: an explicit label whose for attribute holds the input's id, or a label that wraps the input. Either one names the control for assistive technology and makes clicking the label text focus or toggle that control.

open as a page

When a browser submits a plain HTML form, which controls actually end up in the submitted data, and what excludes a control from it?

level: juniorimportance: must knowfreq 62%

basics

~20 s

Only enabled controls that have a non-empty name attribute are submitted. Missing name, disabled, and unchecked checkboxes or radios all send nothing; readonly fields are still sent, and a checkbox with no value attribute sends the string "on".

open as a page

On a login form and on a change-password form, which HTML autocomplete values belong on the password inputs, and what does autocomplete="new-password" change?

level: middleimportance: must knowfreq 60%

basics

~20 s

Login uses autocomplete="username" plus autocomplete="current-password". A change-password form uses current-password for the old value and new-password on both the new and confirm fields, which tells the browser to offer a generated password instead of filling the stored one.

open as a page

HTML form controls expose both checkValidity() and reportValidity(). What does each one do, what do they have in common, and when would you call one over the other?

level: middleimportance: must knowfreq 58%

basics

~10 s

Both return a boolean and fire an invalid event at every failing control. checkValidity() does it silently; reportValidity() additionally shows the browser's message and focuses the first invalid control. Neither one submits the form.

open as a page

Using setCustomValidity() on an HTML form control, how do you make the browser show your own error text — for example "passwords do not match" — and what breaks if you get one step wrong?

level: middleimportance: must knowfreq 52%

basics

~20 s

Call setCustomValidity("message") to mark a control invalid with your own text; the browser then blocks submission and shows that message. You must call setCustomValidity("") once the value becomes acceptable, or the control stays invalid forever.

open as a page

Why is <input type="number"> a poor choice for phone numbers, postal codes and account IDs, and what markup would you use instead?

level: middleimportance: must knowfreq 62%

basics

~20 s

type="number" holds a quantity, not a digit string: anything it cannot parse as a number is read back as an empty string, and spinners, arrow keys and the scroll wheel can change it. Use type="text" with inputmode="numeric", or type="tel" for phones.

open as a page

Why is the placeholder attribute on an HTML input not an acceptable replacement for a <label> element?

level: middleimportance: must knowfreq 70%

basics

~20 s

A placeholder vanishes as soon as the user types, so the field's meaning disappears exactly when it is needed for review and correction. It is a hint, not a name, and is not a dependable accessible name for the control.

open as a page

An HTML form contains <input type="file">. Why must it set enctype="multipart/form-data", and what does the browser send differently from the default encoding?

level: middleimportance: must knowfreq 56%

basics

~20 s

The default encoding, application/x-www-form-urlencoded, can only carry percent-encoded text pairs, so a file input contributes just its filename. multipart/form-data splits the submission into labelled parts separated by a boundary, each able to carry raw bytes plus a filename and its own content type.

open as a page

What changes when an HTML <form> uses method="get" instead of method="post", and how do you choose between them?

level: middleimportance: must knowfreq 70%

basics

~20 s

With method="get" the browser puts the form's entries in the URL query string, so the result is bookmarkable and reloadable; with method="post" it puts them in the request body, which supports file uploads and keeps values out of the URL and history.

open as a page

In an HTML <select>, what value does a chosen <option> submit, and how do you control which option is selected when the page first loads?

level: juniorimportance: should knowfreq 52%

basics

~20 s

An option submits its value attribute, or its text content when no value attribute is present. The selected attribute sets the initial choice; a dropdown with nothing marked selected falls back to its first non-disabled option.

open as a page

Your app asks the user to type a six-digit code sent by SMS. Which HTML autocomplete value makes phones offer that code, and how should the input be marked up?

level: middleimportance: should knowfreq 40%

basics

~20 s

Use a single input with autocomplete="one-time-code". That token lets mobile browsers surface a code just received by SMS as a one-tap suggestion. Splitting the code across six separate boxes defeats it, because the token describes one whole code.

open as a page

An HTML form control exposes a validity property returning a ValidityState object. Which flags does it carry, and how do you use them to tell why a field is invalid rather than just that it is?

level: middleimportance: should knowfreq 45%

basics

~20 s

ValidityState exposes one boolean per failure reason — valueMissing, typeMismatch, patternMismatch, tooShort, tooLong, rangeUnderflow, rangeOverflow, stepMismatch, badInput, customError — plus valid. Test the specific flag to choose the right message instead of inferring it from the value.

open as a page

What does HTML's <dialog> element give you that a hand-built div-and-overlay modal does not, and what happens when a form inside it uses method="dialog"?

level: middleimportance: should knowfreq 46%

basics

~20 s

Opened as a modal, a dialog renders in the top layer, makes the rest of the page inert, moves focus inside, closes on Escape and returns focus afterwards. A form with method="dialog" closes it instead of submitting, setting returnValue from the pressed button.

open as a page

In HTML, how do you give a <textarea> an initial value, and what do its rows and cols attributes actually control?

level: middleimportance: should knowfreq 42%

basics

~20 s

A textarea has no value attribute: its initial text is whatever sits between the opening and closing tags, and a newline right after the opening tag is dropped by the parser. The rows and cols attributes set the visible line count and average character width.

open as a page

What does the HTML inputmode attribute do, and how is it different from an input's type attribute?

level: middleimportance: should knowfreq 42%

basics

~20 s

inputmode is a hint that tells a device which virtual keyboard layout to show. It changes no semantics, no validation and no value handling — unlike type, which selects the control, its value grammar, its built-in validity check and its accessible role.

open as a page

Each radio button in a "Shipping speed" choice already has its own <label>. Why wrap the set in a <fieldset> with a <legend>, and what does that add?

level: middleimportance: should knowfreq 55%

basics

~20 s

Individual labels name the options but nothing names the question they answer. A fieldset groups the controls and its legend supplies the group's name, so a user encountering "Standard" and "Express" knows they are choosing a shipping speed.

open as a page

An HTML form has two submit buttons, Save and Publish. How does the server know which one the user pressed, and how can one button post to a different URL than the form's action?

level: middleimportance: should knowfreq 46%

basics

~20 s

Only the activated submit button contributes its name and value to the submission, so giving each button a name and a distinct value tells the server which was pressed. A button's formaction attribute overrides the form's action URL for that button only.

open as a page

A reviewer asks you to put autocomplete="off" on the password input of your site's login form. Why is that usually the wrong call, and what do browsers actually do with it?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Mainstream browsers deliberately ignore autocomplete="off" on password fields and still offer to save and fill credentials, so the attribute mostly fails to do what the reviewer wants while making the form worse for people relying on a password manager.

open as a page

A checkout page collects a shipping address and a billing address, each with its own street and postal-code inputs. How do you write the autocomplete attributes so the browser fills the two groups separately?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Prefix the field name with a grouping token: autocomplete="shipping street-address" on one group and autocomplete="billing street-address" on the other. For two groups of the same kind, add a section-* prefix such as section-gift shipping street-address.

open as a page

On a freshly loaded page, an empty <input required> already matches the CSS :invalid pseudo-class before the user has typed anything. Why does that happen, and what does :user-invalid do differently?

level: seniorimportance: should knowfreq 40%

basics

~20 s

:invalid reflects constraint state alone, so an untouched empty required field already matches it at page load. :user-invalid matches only after the user has edited the field or attempted submission, which is why error state should key off it.

open as a page

In HTML, what does pairing an <input list> with a <datalist> actually give you, and when is it not enough — forcing you to build a custom combobox?

level: seniorimportance: should knowfreq 44%

basics

~20 s

A datalist attaches browser-rendered suggestions to a text input while leaving it free-text: zero script, native mobile behaviour, no constraint. It falls short when you need control over filtering, styling, rich or multi-line options, multi-select, or dependable screen-reader behaviour.

open as a page

An <input type="date"> shows dd.mm.yyyy to a user in Berlin and mm/dd/yyyy to a user in New York, yet the form sends the same string. How does the native date input separate value from display, and what does that mean in production?

level: seniorimportance: should knowfreq 35%

basics

~20 s

A date input's value is always the ISO-style string yyyy-mm-dd regardless of what the user sees; the displayed format follows the user's browser and OS locale and cannot be set from markup. An incomplete or invalid entry yields an empty string rather than a partial date.

open as a page

In HTML, what does the accept attribute on <input type="file"> actually do, and what does adding multiple change?

level: seniorimportance: should knowfreq 38%

basics

~20 s

accept filters what the operating system's file picker shows by default, using MIME types, wildcards like image/* or extensions like .pdf. It is a convenience hint the user can override, not validation, so the file that arrives can be anything. multiple lets one field carry several files.

open as a page

A cart page renders one row per item, and each row contains <label for="qty">Quantity</label><input id="qty">. What breaks, and how would you fix the labelling?

level: seniorimportance: should knowfreq 42%

basics

~20 s

The id is repeated, and ids must be unique in a document. Every label resolves to the first matching input, so clicking any row's label focuses row one and later inputs end up with no associated label at all.

open as a page

A sign-up form marks required fields with a red asterisk beside the label text. Which users does that leave out, and what makes "required" actually reach everyone?

level: seniorimportance: should knowfreq 38%

basics

~20 s

A red asterisk carries the meaning in colour plus an unexplained symbol. It needs a visible key stating what the asterisk means, the marker inside the label's text so it travels with the field's name, and the required attribute so the control itself exposes the state.

open as a page

Without using any framework, how do you take over a form's submission and send it with fetch while sending exactly the data the browser would have sent, and what is the form's formdata event for?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Listen for the form's submit event, prevent the default navigation, and build new FormData(form, event.submitter) — that reproduces the browser's own entry list. The formdata event fires whenever that list is built, letting a handler append entries for state no control holds.

open as a page

In a signup form, pressing Enter in the email field submits the form, and clicking a "Show password" <button> inside it reloads the page. Explain both behaviours and how you would control them.

level: seniorimportance: should knowfreq 52%

basics

~20 s

Both are default form behaviour. A <button> with no type attribute defaults to type="submit", so the show-password button submits and navigates. Enter in a text field triggers implicit submission, which activates the form's first submit button. Fix the button with type="button"; keep Enter working.

open as a page

showing 1–30 of 32