Input types
The type attribute turns one <input> element into many different controls. The right type gives people the right keyboard on a phone, a picker where it helps, and some validation for free.
Text-like types
<style>label { display: block; margin: 10px 0 4px; font-family: system-ui; }</style>
<label for="t">Text</label> <input id="t" type="text" placeholder="Anything">
<label for="e">Email</label> <input id="e" type="email" placeholder="you@example.com">
<label for="p">Password</label> <input id="p" type="password" value="secret123">
<label for="u">Website</label> <input id="u" type="url" placeholder="https://">
<label for="ph">Phone</label> <input id="ph" type="tel" placeholder="+91 98765 43210">
<label for="s">Search</label> <input id="s" type="search" placeholder="Search lessons">On a phone, email brings up a keyboard with @, tel a number pad, and url a keyboard with / and .com.
Numbers and ranges
<style>label { display: block; margin: 10px 0 4px; font-family: system-ui; }</style>
<label for="qty">Quantity (1 to 10)</label>
<input id="qty" type="number" min="1" max="10" step="1" value="2">
<label for="vol">Volume</label>
<input id="vol" type="range" min="0" max="100" value="60">
<output id="volOut" for="vol">60</output>
<script>
const vol = document.querySelector("#vol");
vol.addEventListener("input", () => {
document.querySelector("#volOut").textContent = vol.value;
});
</script>number has up and down arrows and rejects letters. range is a slider, for when the feel matters more than the exact value.
Dates, times and colours
<style>label { display: block; margin: 10px 0 4px; font-family: system-ui; }</style>
<label for="d">Date</label> <input id="d" type="date" min="2026-01-01">
<label for="tm">Time</label> <input id="tm" type="time" value="09:30">
<label for="dt">Date and time</label> <input id="dt" type="datetime-local">
<label for="m">Month</label> <input id="m" type="month">
<label for="c">Colour</label> <input id="c" type="color" value="#5a48f5">The browser supplies the picker. Whatever format the picker displays, the value always arrives in a fixed form, such as 2026-03-14 for a date.
Choices
<style>body { font-family: system-ui; } label { margin-right: 12px; }</style>
<fieldset>
<legend>Topics you like</legend>
<label><input type="checkbox" name="topic" value="web" checked> Web</label>
<label><input type="checkbox" name="topic" value="data"> Data</label>
<label><input type="checkbox" name="topic" value="cloud"> Cloud</label>
</fieldset>
<fieldset>
<legend>Plan</legend>
<label><input type="radio" name="plan" value="free" checked> Free</label>
<label><input type="radio" name="plan" value="pro"> Pro</label>
</fieldset>- Checkboxes allow any number of choices; radio buttons that share a
nameallow exactly one. <fieldset>and<legend>group related controls and give the group a name that screen readers announce.- Putting the input inside its
<label>connects the two without needingforandid.
Files
<label for="f">Upload a profile picture</label><br>
<input id="f" type="file" accept="image/*">
<p id="info" style="font-family: system-ui"></p>
<script>
document.querySelector("#f").addEventListener("change", (e) => {
const file = e.target.files[0];
if (file) {
document.querySelector("#info").textContent =
`${file.name}: ${Math.round(file.size / 1024)} KB, ${file.type}`;
}
});
</script>accept filters what the file picker offers, and multiple lets people choose several files at once. Nothing is uploaded until a form or script sends it.
Suggestions with datalist
<label for="lang">Favourite language</label>
<input id="lang" list="langs" placeholder="Start typing...">
<datalist id="langs">
<option value="Python">
<option value="JavaScript">
<option value="Java">
<option value="SQL">
<option value="C++">
</datalist>Unlike a <select>, a datalist only suggests: people can still type something else.
Handy attributes
| Attribute | Effect |
|---|---|
placeholder | hint text while the field is empty (it's not a replacement for a label) |
value | the starting value |
disabled | greyed out, can't be used, and not submitted |
readonly | can't be edited, but is submitted |
autocomplete | helps the browser fill it in: email, name, new-password... |
autofocus | puts the cursor in this field when the page loads |
type="hidden" | invisible, but submitted: for values like ids that the server needs back |