HTML Input Types

The <input> element is the single most versatile tag in HTML forms. A single element, <input>, can turn into a text box, a checkbox, a slider, a date picker, or a file uploader — all controlled by one attribute: type. Understanding the full range of input types matters because each one changes three things at once: what the browser renders, what keyboard or picker mobile devices show, and what built-in validation rules apply before the form can submit.

Overview / How it works

Every <input> is a void element — it never has a closing tag or children, and it never wraps text content the way <button> or <a> do. Instead, everything about it is expressed through attributes. The most important attribute is type. If you omit type entirely, the browser defaults to type=\"text\", which is why so many older forms only ever use plain text boxes even when a more specific type would serve the user better.

When the HTML parser builds the DOM, an <input> becomes a single HTMLInputElement node. That node exposes properties like .value, .checked, and .validity to JavaScript, but even without any script, the browser itself uses the type value to decide: (1) what UI to render (a text caret, a round radio circle, a slider track), (2) what on-screen keyboard to show on touch devices (a numeric pad for type=\"tel\", an @ key for type=\"email\"), and (3) what constraint-validation rules to apply automatically when the surrounding <form> is submitted (rejecting malformed emails, out-of-range numbers, or empty required fields).

This is the key idea to internalize: choosing the right type is not cosmetic. It is free validation, free accessibility, and a better mobile experience, all supplied by the browser with zero JavaScript.

Syntax

<input type=\"TYPE_VALUE\" name=\"fieldName\" id=\"fieldId\" value=\"defaultValue\" placeholder=\"hint text\" required>
  • type — determines the control’s behavior and appearance; see the table below for the full list.
  • name — the key used when the form data is submitted; without it, the field’s value is not sent at all.
  • id — used to associate a <label> with this control via the label’s for attribute.
  • value — the initial value shown (or, for checkboxes/radios, the value submitted when checked).
  • placeholder — light gray hint text shown only when the field is empty; it is not a substitute for a real <label>.
  • required — a boolean attribute that blocks form submission until the field has a valid value.
  • Type-specific attributes such as min, max, step, pattern, maxlength, and accept only apply to certain types, described below.

Reference: common input types

type value Renders as Typical use
text Single-line text box Names, general short text
email Text box with email validation Email addresses
password Text box that masks characters Passwords
number Text box with up/down steppers Quantities, ages
tel Text box, numeric keypad on mobile Phone numbers
url Text box with URL validation Website links
search Text box styled for search (often with a clear button) Site search bars
date Date picker Birthdates, appointment dates
time Time picker Meeting times
checkbox Square toggle box On/off, multi-select options
radio Round toggle, exclusive within a shared name Single choice from a set
range Slider Approximate numeric values (volume, rating)
color Color swatch picker Choosing a color value
file File chooser button Uploading files
hidden Not rendered at all Sending data the user shouldn’t edit
submit Clickable button Submitting the form

Examples

Example 1: Basic text-based types

<form>
  <label for=\"name\">Full name</label>
  <input type=\"text\" id=\"name\" name=\"name\" placeholder=\"Jane Doe\">

  <label for=\"email\">Email</label>
  <input type=\"email\" id=\"email\" name=\"email\" required>

  <label for=\"pwd\">Password</label>
  <input type=\"password\" id=\"pwd\" name=\"pwd\" minlength=\"8\" required>
</form>

Result: Three labeled fields stack vertically: a plain text box, an email box that shows an @ key on mobile keyboards and rejects submission if the text isn’t a valid email shape, and a password box whose characters are rendered as dots. If the email or password field is left empty, the browser shows a small native validation bubble instead of submitting.

This example shows how three visually similar text boxes behave completely differently once type changes, purely from browser defaults.

Example 2: Numeric, date, and choice types

<form>
  <label for=\"age\">Age</label>
  <input type=\"number\" id=\"age\" name=\"age\" min=\"0\" max=\"120\" step=\"1\">

  <label for=\"dob\">Date of birth</label>
  <input type=\"date\" id=\"dob\" name=\"dob\">

  <p>Preferred contact:</p>
  <input type=\"radio\" id=\"contact-email\" name=\"contact\" value=\"email\" checked>
  <label for=\"contact-email\">Email</label>
  <input type=\"radio\" id=\"contact-phone\" name=\"contact\" value=\"phone\">
  <label for=\"contact-phone\">Phone</label>

  <label for=\"volume\">Notification volume</label>
  <input type=\"range\" id=\"volume\" name=\"volume\" min=\"0\" max=\"10\">
</form>

Result: The age field shows a number box with tiny up/down arrows and rejects values outside 0–120. The date field opens a native calendar picker when clicked. The two radio buttons are mutually exclusive (only one can be selected) because they share name=\"contact\", and \”Email\” starts pre-selected because of its checked attribute. The range input renders as a draggable slider from 0 to 10.

Notice that min, max, and step only make sense for numeric-like types (number, range, date); putting them on a text input has no effect at all.

Example 3: A realistic sign-up form combining multiple types

<form>
  <h2>Create account</h2>

  <label for=\"username\">Username</label>
  <input type=\"text\" id=\"username\" name=\"username\" pattern=\"[A-Za-z0-9_]{3,16}\" required>

  <label for=\"signup-email\">Email</label>
  <input type=\"email\" id=\"signup-email\" name=\"signup-email\" required>

  <label for=\"avatar\">Profile picture</label>
  <input type=\"file\" id=\"avatar\" name=\"avatar\" accept=\"image/*\">

  <label for=\"theme\">Favorite color</label>
  <input type=\"color\" id=\"theme\" name=\"theme\" value=\"#3366ff\">

  <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>
  <label for=\"terms\">I agree to the terms</label>

  <input type=\"submit\" value=\"Create account\">
</form>

Result: A full sign-up form renders: a username field that only accepts 3–16 letters, digits, or underscores (enforced by the pattern regular expression), an email field, a file picker restricted to image files, a color swatch defaulting to blue, a required checkbox, and a submit button labeled \”Create account\”. Trying to submit without checking the box or with an invalid username triggers the browser’s built-in validation message and blocks submission.

This example shows how several type-specific attributes (pattern, accept) layer on top of the base type to add precise constraints without any JavaScript.

How it works step by step

  • The HTML parser reads the <input> tag and, because it’s a void element, immediately closes the node — there is no matching </input> and none should be written.
  • The browser reads the type attribute (case-insensitively) and looks it up against its known list. If the value is unrecognized or missing, it falls back to text.
  • Based on the resolved type, the rendering engine picks a built-in UI widget — this is why a date input looks nothing like a checkbox, even though both come from the same tag.
  • Type-specific attributes (min, max, pattern, accept, step) are parsed and attached to that widget’s internal constraint set.
  • When the form is submitted, the browser runs constraint validation on every field before letting the submission proceed, checking required, type format, and any min/max/pattern rules — and shows a native error bubble on the first invalid field if something fails.

Common Mistakes

Mistake 1: Using type=\"text\" for everything.

<label for=\"em\">Email</label>
<input type=\"text\" id=\"em\" name=\"em\">

This works, but it throws away free validation and the mobile @ keyboard. Use the semantic type instead:

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

Mistake 2: Radio buttons with different name values.

<input type=\"radio\" name=\"plan1\" value=\"basic\"> Basic
<input type=\"radio\" name=\"plan2\" value=\"pro\"> Pro

Because each radio has a unique name, both can be selected at once — defeating the purpose of a single-choice group. All radios in one group must share the same name:

<input type=\"radio\" name=\"plan\" value=\"basic\"> Basic
<input type=\"radio\" name=\"plan\" value=\"pro\"> Pro

Mistake 3: Forgetting the name attribute entirely.

<input type=\"text\" id=\"city\">

Without name, this field’s value is never included when the form is submitted — only name/value pairs get sent. Always pair every input with a name.

Best Practices

  • Always choose the most specific type available (email, tel, number, date) instead of defaulting to text — it gives free validation and better mobile keyboards.
  • Always pair an input with a real <label> connected via for/id; never rely on placeholder alone, since placeholder text disappears once the user starts typing.
  • Group related radio inputs under the same name, and give each a unique value.
  • Use required, min, max, and pattern to catch obvious errors client-side, but never rely on them as your only validation — always re-validate on the server too.
  • Remember that styling color, size, and layout of inputs is done with CSS, not HTML attributes — this course covers structure only.
  • Use accept on type=\"file\" to hint at expected file formats, but don’t treat it as a security control since it can be bypassed.

Practice Exercises

  • Build a small form with a tel input for a phone number and a url input for a personal website, each with a proper <label>.
  • Create a group of three checkboxes representing hobbies (e.g. reading, gaming, cooking) that all share meaningful but distinct name attributes so each can be submitted independently, and give the group a heading.
  • Build a \”schedule an appointment\” form using type=\"date\" and type=\"time\" together, plus a range input for a 1–5 urgency rating.

Summary

  • The type attribute on <input> controls rendering, mobile keyboard behavior, and built-in validation all at once.
  • <input> is a void element — it never has a closing tag or content.
  • Text-like types (email, tel, url, number) add automatic format validation with zero JavaScript.
  • Radio buttons must share a name to behave as an exclusive group; checkboxes are independent toggles.
  • Every meaningful input needs a name attribute to be submitted, and a connected <label> for accessibility.