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’sforattribute.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, andacceptonly 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
typeattribute (case-insensitively) and looks it up against its known list. If the value is unrecognized or missing, it falls back totext. - Based on the resolved type, the rendering engine picks a built-in UI widget — this is why a
dateinput looks nothing like acheckbox, 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 anymin/max/patternrules — 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
typeavailable (email,tel,number,date) instead of defaulting totext— it gives free validation and better mobile keyboards. - Always pair an input with a real <label> connected via
for/id; never rely onplaceholderalone, since placeholder text disappears once the user starts typing. - Group related
radioinputs under the samename, and give each a uniquevalue. - Use
required,min,max, andpatternto 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
acceptontype=\"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
telinput for a phone number and aurlinput 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
nameattributes so each can be submitted independently, and give the group a heading. - Build a \”schedule an appointment\” form using
type=\"date\"andtype=\"time\"together, plus arangeinput for a 1–5 urgency rating.
Summary
- The
typeattribute 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
nameto behave as an exclusive group; checkboxes are independent toggles. - Every meaningful input needs a
nameattribute to be submitted, and a connected <label> for accessibility.
