Input & Form Attributes
An <input> element does very little until you add attributes. Attributes decide its starting value, its hint text, whether it can be edited, which files it accepts, what the browser may fill in automatically, and even which form it belongs to. The <form> element and its buttons have attributes of their own that decide where and how the data travels.
This lesson is a practical tour of those attributes. The checking attributes, such as required and pattern, have their own lesson, Built-in Form Validation, so here they get only a short summary.
Starting values and hints
valuesets the starting value of a field. When the user types, the field's current value changes, but the attribute does not. A reset button puts the field back to the attribute's value.placeholdershows a short example inside an empty field, such ase.g. 124001. It disappears as soon as the user types, so it never replaces a<label>.sizesets the visible width of a text field in characters (the default is 20). CSSwidthis usually a better choice.maxlengthstops the user typing more than a set number of characters.readonlylets the user see, select and copy the value but not change it. The value is still sent.disabledswitches the field off completely. It cannot be focused and its value is not sent.
The full comparison of readonly and disabled is in Form Elements. This example shows the difference in what is sent.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Order form</title>
<style>label { display: block; margin-top: 10px; }</style>
</head>
<body>
<form action="#" method="post">
<label for="order">Order number</label>
<input id="order" name="order" value="RT-20481" readonly>
<label for="city">Delivery city</label>
<input id="city" name="city" value="Rohtak">
<label for="pin">PIN code</label>
<input id="pin" name="pin" placeholder="e.g. 124001" maxlength="6" inputmode="numeric">
<label for="coupon">Coupon (not available for this order)</label>
<input id="coupon" name="coupon" value="DIWALI10" disabled>
<p>
<button type="submit">Confirm</button>
<button type="reset">Undo my changes</button>
</p>
</form>
<p>Sent: <output id="sent"></output></p>
<script>
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // demo only: nothing is sent
document.querySelector("#sent").textContent = new URLSearchParams(new FormData(form)).toString();
});
</script>
</body>
</html>Press Confirm: the read-only order number is sent, the disabled coupon is not. Change the city to "Jaipur", then press "Undo my changes": the city goes back to "Rohtak", because that is what its value attribute says.
Limits: a quick summary
| Attribute | Works on | Effect |
|---|---|---|
required | Most inputs, <select>, <textarea> | The field must not be empty |
min, max | Numbers, ranges, dates and times | Lowest and highest allowed value |
step | Numbers, ranges, dates and times | Allowed jumps between values; step="any" allows any value |
minlength, maxlength | Text-like inputs, <textarea> | Fewest and most characters |
pattern | Text-like inputs | The whole value must match a regular expression |
One detail about step surprises people: the steps are counted from min. With min="1" and step="2", the allowed values are 1, 3, 5 and so on, so 4 is rejected. Without min, steps count from the field's value, or from zero.
Files, lists and multiple values
The boolean multiple attribute allows more than one value:
- On
type="file", the user can choose several files at once. - On
type="email", the user can type several addresses separated by commas. - On
<select>, the list shows several rows and the user can pick more than one option.
For file inputs, accept suggests which files to offer, as a comma-separated list of types (image/*, application/pdf) or extensions (.pdf, .jpg). It is only a hint for the file picker; users can often still choose other files, so the server must check every upload. On many phones, capture="environment" opens the back camera directly, and capture="user" opens the front camera.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Admission documents</title>
<style>label { display: block; margin-top: 10px; }</style>
</head>
<body>
<form action="#" method="post" enctype="multipart/form-data">
<label for="docs">Marksheets and ID proof (images or PDF)</label>
<input id="docs" name="docs" type="file" accept="image/*,.pdf" multiple>
<ul id="chosen"></ul>
<label for="cc">Send copies to (separate addresses with commas)</label>
<input id="cc" name="cc" type="email" multiple placeholder="e.g. ananya@example.com, farhan@example.com">
</form>
<script>
document.querySelector("#docs").addEventListener("change", (event) => {
const list = document.querySelector("#chosen");
list.replaceChildren();
for (const file of event.target.files) {
const item = document.createElement("li");
item.textContent = `${file.name} (${Math.round(file.size / 1024)} KB)`;
list.append(item);
}
});
</script>
</body>
</html>Choose two or three files and the list shows each name and size. Notice enctype="multipart/form-data" on the form: without it, a form sends only the names of the files, never their contents. File Uploads shows the server side.
The list attribute connects an input to a <datalist> of suggestions by its id, also covered in Form Elements.
autocomplete and autofocus
The autocomplete attribute tells the browser what a field contains, so it can offer saved details. You met the common values, such as name, email, tel, postal-code and one-time-code, in Built-in Form Validation. Two more tricks help on checkout pages:
<label for="ship-pin">Delivery PIN code</label>
<input id="ship-pin" name="ship_pin" autocomplete="shipping postal-code">
<label for="bill-pin">Billing PIN code</label>
<input id="bill-pin" name="bill_pin" autocomplete="billing postal-code">
<label for="new-pass">Choose a password</label>
<input id="new-pass" name="password" type="password" autocomplete="new-password">The words shipping and billing tell the browser that these are two different addresses, so it does not fill both with the same one. new-password asks the browser to suggest a strong new password instead of filling in a saved one. autocomplete="off" on a field or on the whole <form> asks the browser not to fill it, but browsers may ignore it for logins.
autofocus puts the cursor in a field when the page loads. Use it on one field at most, and only when the page exists for that field, such as a search page. More in Interactive Attributes.
Attributes of the form element
| Attribute | Meaning | Default |
|---|---|---|
action | URL that receives the data | The current page |
method | get, post, or dialog (closes a <dialog>) | get |
enctype | How POST data is packed: application/x-www-form-urlencoded, multipart/form-data (needed for files) or text/plain | application/x-www-form-urlencoded |
target | Where to show the response, such as _blank for a new tab | The same tab |
novalidate | Skip the browser's validation | Validation on |
autocomplete | on or off for every field inside | on |
name | A name for scripts to find the form | None |
accept-charset | Character encoding; the only valid value is UTF-8 | The page's encoding |
Controls outside the form, and buttons that override it
Sometimes a control cannot sit inside its <form>, for example a "Search" box in the header that belongs to a filter form further down, or a "Save" button in a toolbar at the bottom of the screen. The form attribute connects any input, select, textarea or button to a form by the form's id.
A submit button can also override the form's own settings, just for that button:
| Button attribute | Overrides |
|---|---|
formaction | action |
formmethod | method |
formenctype | enctype |
formtarget | target |
formnovalidate | Turns validation off for this button only |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Article editor</title>
<style>footer { margin-top: 16px; padding: 10px; background: #eef; }</style>
</head>
<body>
<form id="article" action="/articles/publish" method="post">
<label for="headline">Headline</label>
<input id="headline" name="headline" required>
</form>
<p>This textarea is outside the form, but still belongs to it:</p>
<textarea name="body" form="article" rows="3" cols="40">Rohtak wins the inter-district cricket final.</textarea>
<footer>
<button form="article">Publish</button>
<button form="article" formaction="/articles/drafts" formnovalidate>Save draft</button>
<button form="article" formaction="/articles/preview" formmethod="get" formtarget="_blank">Preview</button>
</footer>
<pre id="report"></pre>
<script>
const form = document.querySelector("#article");
form.addEventListener("submit", (event) => {
event.preventDefault(); // demo only: show what would happen
const b = event.submitter;
document.querySelector("#report").textContent =
`Button: ${b.textContent}\n` +
`Action: ${b.getAttribute("formaction") ?? form.getAttribute("action")}\n` +
`Method: ${(b.getAttribute("formmethod") ?? form.getAttribute("method")).toUpperCase()}\n` +
`Target: ${b.getAttribute("formtarget") ?? "same tab"}\n` +
`Data: ${new URLSearchParams(new FormData(form))}`;
});
</script>
</body>
</html>With an empty headline, Publish and Preview are stopped by required, but "Save draft" goes through because of formnovalidate. Each button reports a different action, method or target, and the textarea's text is included even though it sits outside the <form> element.
Common mistakes
- Using
placeholderinstead of a label. The hint vanishes while typing; always add a<label>. - Using
disabledon a value the server needs. Disabled fields are not sent; usereadonly. - File uploads without
enctype="multipart/form-data"andmethod="post". Only the file names arrive. - Trusting
accept. It only filters the file picker; check uploads on the server. - Writing
form="#article". Theformattribute takes the plain id:form="article".
Key points
valuesets the starting value; reset buttons return to it.placeholderis a short example, not a label.readonlyfields are sent;disabledfields are not.multipleallows several files, emails or options;accepthints which files to offer.- Precise
autocompletevalues, includingshippingandbilling, help browsers fill forms correctly. - The form's
action,method,enctypeandtargetdecide where and how data travels. - The
formattribute links controls placed outside a form, andformaction,formmethod,formtargetandformnovalidateoverride the form for one button.
Exercise
Create a "Job application" form with id="apply" that posts to /apply and can upload files. Include a read-only job code JPR-112, a full name field with the right autocomplete value, and a file input that accepts several PDF files. Place the buttons below the form, outside it: a "Submit application" button and a "Save and finish later" button that sends to /apply/save and skips validation. Make the name field required.
Show solution
<form id="apply" action="/apply" method="post" enctype="multipart/form-data">
<label for="job">Job code</label>
<input id="job" name="job" value="JPR-112" readonly>
<label for="fullname">Full name</label>
<input id="fullname" name="fullname" autocomplete="name" required>
<label for="cv">CV and certificates (PDF)</label>
<input id="cv" name="cv" type="file" accept=".pdf,application/pdf" multiple>
</form>
<button form="apply">Submit application</button>
<button form="apply" formaction="/apply/save" formnovalidate>Save and finish later</button>Both buttons sit outside the form but join it through form="apply". The second one changes the destination with formaction and skips the required check with formnovalidate.
Quick Quiz
1. The user changes a field that has value="Pune" to "Kochi" and then presses a reset button. What does the field show?
Reset returns each field to the value written in its value attribute.
2. Which field is sent when the form is submitted?
Read-only fields are sent; disabled fields and fields without a name are not.
3. With min="1" and step="2", which value is valid?
Steps count from min: 1, 3, 5, 7 and so on.
4. A "Save draft" button should skip validation and send to /drafts. Which attributes does it need?
Button attributes starting with form override the form's settings for that button only.
Learn HTML with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
