HTML forms · 2 / 9
lesson 2

Input types in 2026

Picking the right input type changes the keyboard, the validation, and the controls — for one word in your markup.

~ 17 min read·lesson 2 of 9
0 / 9

Every <input> has a type attribute. You probably default to type="text" and move on. That's fine — it works. But the type is doing a lot more than picking which characters are allowed. It changes the keyboard a phone shows, the validation rules the browser applies, the controls the browser draws (a date picker, a color swatch), and what password managers offer to fill.

This lesson is a tour of the types that earn their keep, with the concrete effect of each.

The text family

Several types are all essentially text fields under the hood, but each gives the browser a hint about what shape of text to expect.

  • text — plain text. Default. No constraints. Use only when none of the more specific types fit.
  • email — text, but the browser checks it looks like something@something.something and refuses to submit otherwise. Mobile keyboards add the @ and . keys.
  • url — text expected to be a URL. Mobile keyboards add / and .com.
  • tel — a phone number. Mobile keyboards switch to the dial-pad layout. No format validation (phone numbers vary too much by country).
  • search — a search box. Some browsers add an "x" to clear it. Otherwise text.
  • password — masks the typed characters with dots. Tells the browser to suggest password manager autofill.
text-family.html
<label>Email <input name="email" type="email" required></label>
<label>Website <input name="url" type="url"></label>
<label>Phone <input name="tel" type="tel"></label>
<label>Search <input name="q" type="search"></label>
<label>Password <input name="pw" type="password" required></label>

The user types into all five the same way. But the experience is different on mobile (different keyboards), in the browser (different validation), and to password managers (which know to fill email and password together).

A common mistake: type="number" for a phone number. Numbers can have leading zeros, plus signs, parentheses, and spaces — all of which a numeric input strips. Use type="tel" for phones, always.

Numbers, dates, ranges

These types render a control, not just a text field — a stepper, a calendar, a slider.

number — a numeric input. The browser shows up/down stepper buttons; mobile shows a numeric keyboard. Pair with min, max, and step to constrain the value.

number.html
<label>Quantity <input name="qty" type="number" min="1" max="10" step="1" value="1"></label>

step="1" means whole numbers only. step="0.01" would allow two decimal places. The browser refuses to submit values out of range or not aligned to the step.

date — a date picker. The browser draws a calendar. The submitted value is always YYYY-MM-DD, regardless of the user's locale display.

time — a time picker. The submitted value is HH:MM or HH:MM:SS.

datetime-local — a date and time picker. Submits YYYY-MM-DDTHH:MM.

month — picks a month. Submits YYYY-MM.

week — picks an ISO week. Submits YYYY-W##. Niche but useful for scheduling apps.

dates.html
<label>Birthday <input name="dob" type="date" max="2026-04-29"></label>
<label>Wake up <input name="alarm" type="time" step="60"></label>

The date input refuses dates after the max. The time input's step="60" says one-minute granularity (the default is one second).

range — a slider. Visible position only; the user does not see the numeric value unless you wire one up.

range.html
<label for="vol">Volume</label>
<input id="vol" name="vol" type="range" min="0" max="100" step="1" value="50">

Use range for a value where the position matters more than precision (volume, opacity, brightness). Use number when the user might want to type "50.5".

Tip

Date and time inputs have shaky support on Linux Firefox and a few legacy browsers — they may fall back to text. The submitted format (YYYY-MM-DD) stays the same; the picker just doesn't appear. Plan for that and your form keeps working.

check your understanding
You're collecting a quantity from 1 to 100, where decimals are not meaningful. The user should be able to type the value or use a stepper. Which markup is right?

Choice inputs

Three types let the user pick from options:

checkbox — a yes/no toggle. Multiple checkboxes with the same name send all the checked values together (in URL form: tags=bread&tags=pastry).

radio — a one-of-many choice. Radios with the same name form a group; only one can be selected.

choice.html
<fieldset>
<legend>Shipping speed</legend>
<label><input type="radio" name="speed" value="standard" checked> Standard</label>
<label><input type="radio" name="speed" value="express"> Express</label>
<label><input type="radio" name="speed" value="next-day"> Next day</label>
</fieldset>

<fieldset>
<legend>Add-ons</legend>
<label><input type="checkbox" name="addon" value="gift-wrap"> Gift wrap</label>
<label><input type="checkbox" name="addon" value="message"> Personal message</label>
</fieldset>

The radios share name="speed" — the browser enforces "one only". The checkboxes share name="addon" — the user can pick zero, one, or both. The <fieldset> and <legend> group them visually and accessibly (covered in lesson 3).

<select> is not an input — it is a separate element — but it fills the same niche for "pick one of many" when the list is long enough that radios would be unwieldy.

select.html
<label for="country">Country</label>
<select id="country" name="country">
<option value="">Pick one</option>
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="mx">Mexico</option>
</select>

The first <option> with value="" acts as a placeholder. Combine with required on the <select> and the browser will refuse to submit until the user picks a real option.

For multi-select, add multiple to the <select> — the user can pick more than one (Cmd/Ctrl-click). Most designers prefer checkboxes for that interaction, though.

color, file, hidden

Three more types, each useful in a narrow case.

color — opens the OS color picker. Submits a hex value like #3b82f6.

color.html
<label>Theme color <input name="theme" type="color" value="#3b82f6"></label>

file — file picker. Covered in detail in lesson 7. Remember the form needs enctype="multipart/form-data" for the bytes to reach the server.

hidden — invisible input that ships data along with the form. Used to send context the user did not type — a CSRF token, an item id, the page they came from.

hidden.html
<form action="/cart/add" method="post">
<input type="hidden" name="product_id" value="42">
<input type="hidden" name="csrf" value="abc123">
<button type="submit">Add to cart</button>
</form>

The user clicks "Add to cart". The server receives product_id=42 and the CSRF token, even though the user never typed them.

Watch out

type="hidden" is hidden from the user, not from the page source. Anyone can read or modify the value with DevTools. Never put secrets in a hidden input. Use it for context the server can validate (a CSRF token issued for that session) or for non-sensitive identifiers (a product id).

Summary table

A short cheat-sheet for the types that earn their keep on most forms:

cheat-sheet.html
text       — plain text, the fallback
email      — checks @, mobile keyboard adds @ and .
tel        — dial-pad keyboard, no format validation
url        — checks for protocol, mobile keyboard adds / and .com
search     — text with a clear button on some browsers
password   — masks input, password manager friendly

number     — stepper + numeric keyboard, with min/max/step
range      — slider; position-first, value-second
date       — calendar picker; submits YYYY-MM-DD
time       — time picker; submits HH:MM
color      — OS color picker; submits #RRGGBB

checkbox   — boolean
radio      — one-of-many (group by name)

file       — file picker; needs multipart enctype on the form
hidden     — ship context with the form, no user-visible field

The decision tree: pick the most specific type that describes the data. text is the fallback when nothing else fits.

check your understanding
A user enters their phone number into an <input type="number"> field. Their number starts with a 0 (a regional prefix in their country). What does the browser store as the field's value?
check your understanding
You set up a "Newsletter" sign-up with a single email field. You want password managers to recognize the field and your mobile users to get the "@" key on their keyboard. What's the smallest correct markup?
check your understanding
You add a <input type="hidden" name="role" value="admin"> to your form so the server treats the user as an admin. A user opens DevTools. What can they do?
← prevnext lesson →
KeepLearningcertificate
for completing
HTML forms
0 of 9 read