Problem Solved

HTML · input types

Home › Courses › HTML › Problems › Input types
📄 Reference · 4 min read

The 20 HTML input types.
What each one does.

The type attribute on controls three things: the keyboard layout on mobile, the native validation, and the picker UI. Using the right type is free UX — the browser does work you'd otherwise have to write in JavaScript. This page is the complete reference: what each type triggers, what it validates, and when to pick it.

Short answer: Use type="email" for email (validates format, shows @ on mobile), type="tel" for phone (phone keypad, no format check), type="number" for quantities (spinners, numeric keyboard), type="date" for dates (calendar picker), type="file" for uploads. The type is a signal to the browser — better keyboard, better validation, better UX. Never use type="text" for everything.

✅ The complete list

Grouped by purpose.

Text-like inputs

type="text"

Any string. The fallback. Use only when no more specific type applies.

type="email"

Valid email format. Shows @ and . on mobile. Native validation blocks invalid formats.

type="tel"

Phone number. Shows phone keypad. No format validation — use pattern if needed.

type="url"

Full URL. Requires protocol (https://). Shows .com and / on mobile.

type="password"

Masked text. Dots instead of characters. No clipboard, no autocomplete (usually).

type="search"

Search input. iOS shows Search button. Some browsers show clear × inside the field.

Numeric inputs

type="number"

Numeric value. Spinners on desktop. Supports min, max, step. Rejects non-numeric input.

type="range"

Slider. Value is a number in [min, max]. No spinner. Good for volume, brightness, price filters.

Date and time inputs

type="date"

Calendar picker. Submits YYYY-MM-DD. Local date, no timezone.

type="time"

Time picker. Submits HH:MM (or with seconds). No date, no timezone.

type="datetime-local"

Date + time. Submits YYYY-MM-DDTHH:MM. Local time, no timezone.

type="month"

Year and month. Submits YYYY-MM. Good for credit card expiry.

type="week"

ISO week. Submits YYYY-Www. Rarely used — limited browser support.

Choice inputs

type="checkbox"

On/off. Multiple can be checked. Use a group with the same name for multi-select.

type="radio"

One of a group. Same name across the group — only one can be selected. Use required on any one to require a choice.

type="color"

Color picker. Submits hex like #ff6600. Supported by all modern browsers.

type="file"

File upload. Add multiple for multi-select, accept for file types. Requires enctype="multipart/form-data" on the form.

Button and hidden inputs

type="submit"

Submit button. Default type for <button> inside a form. Fires validation, sends the form.

type="reset"

Clears the form. Rarely used — surprising to users. Prefer a custom reset button.

type="button"

Plain button. No default action. Use for JS handlers that don't submit the form.

type="image"

Image submit. Like submit, but the button is an image. Sends click coordinates. Rarely used.

type="hidden"

Not visible. Submits a value with the form. Use for CSRF tokens, IDs. No validation.

✅ A complete form example

All the common types in one form.

input-types.html
Preferred contact
type="email" → validates format, mobile @ key
type="tel" → mobile phone keypad, no validation
type="number" → numeric keyboard, spinners, min/max
type="date" → calendar picker, submits YYYY-MM-DD
type="color" → color picker, submits #rrggbb
type="file" → file picker, needs enctype on form
type="checkbox" → on/off, multi-select as a group
type="radio" → one of group, same name, one value

⚠️ file input requires enctype="multipart/form-data"
⚠️ radio requires one option to be checked (required on one)

Don't use type="number" for phone numbers or credit cards. It looks right — numeric input, numeric keyboard — but type="number" adds spinner arrows, rejects leading zeros (breaks ZIP codes and card numbers), treats + as invalid, and rejects formatted values like (555) 123-4567. Use type="tel" for phone numbers and type="text" with inputmode="numeric" and a pattern for credit cards. The right type is about the data, not the keyboard.

⚠️ Common mistakes

The input-type mistakes that cost real time.

1. type="text" for everything

Missing all the native benefits. Fix: pick the type that matches the data.

2. type="number" for phone / credit card

Breaks leading zeros, rejects +. Fix: type="tel" or type="text" inputmode="numeric".

3. type="email" for username

Enforces @ and domain — blocks valid usernames. Fix: type="text".

4. File input without enctype

The form sends text-only — files are lost. Fix: enctype="multipart/form-data" on the form.

5. Radio buttons with different names

Each is its own group — all can be selected. Fix: same name across the group.

6. Multiple checkboxes without values

Server can't distinguish which were checked. Fix: give each a distinct value.

7. type="date" with a placeholder

Placeholders don't work on date inputs — the picker overrides. Fix: use a label instead.

8. type="submit" with JavaScript preventDefault

No navigation, no fetch. Fix: remove preventDefault, or send the data in the handler.

❓ Frequently asked

What are the HTML input types?

HTML5 has 22 input types: text, email, tel, url, password, search, number, range, date, time, datetime-local, month, week, color, file, checkbox, radio, hidden, submit, reset, button, image. Each controls the keyboard layout (type=email shows @ on mobile), the native validation (type=email enforces @ and a domain), and the picker (type=date shows a calendar). Use the most specific type — text is the fallback, not the default choice.

What is the difference between type=text and type=email?

type=text accepts any string. type=email enforces a valid email format (local@domain), shows the @ and . keys on mobile keyboards, and enables native validation. If the user types not-an-email and submits, the browser blocks it with a message. For users' email addresses, always use type=email — the type is a signal to the browser, the mobile keyboard, and screen readers. It costs nothing and improves UX.

What is type=tel for?

type=tel is for telephone numbers. It does not validate format — phone number formats vary by country and there is no universal pattern the browser can enforce. Its main benefit is the mobile keyboard: type=tel shows the phone keypad (0-9, +, *, #). Use it with pattern if you need a specific format, and minlength/maxlength for length. Don't use type=number for phone numbers — it adds spinners and doesn't handle leading zeros or plus signs well.

When should I use type=number vs type=range?

Use type=number when the user needs to enter a specific numeric value (quantity, age, price). Use type=range when the user should pick from a continuous scale and precision doesn't matter (volume, brightness, price filter). Both support min, max, and step. type=number shows a text field with spinners and accepts keyboard input. type=range shows a slider and only allows values in the defined range. Pick based on whether the user knows the exact value they want.

What is type=search for?

type=search is semantically a search input. It renders like text on most browsers, but on iOS it shows a search keyboard with a Search button, and on some desktop browsers it shows a clear button (×) inside the field. The benefit is small but free: the browser knows this is a search field and adjusts accordingly. Use it for search forms. If you don't need the semantic hint, text works fine too.

What is the difference between type=date and type=datetime-local?

type=date shows a calendar picker for a date (year, month, day). type=datetime-local shows a date and a time picker — useful for scheduling events in the user's local timezone. Both submit a string like 2026-11-02 (date) or 2026-11-02T14:30 (datetime-local). Neither submits a timezone — the value is the user's local time. If you need UTC or a specific timezone, handle the conversion on the server or in JavaScript.

🔗 Related

← All HTML problems
Problem solved · HTML