🎛️ Input Types and Attributes
The <input> element is the workhorse of every form — and its type attribute turns one tag into dozens of specialized tools. This lesson tours the input types worth knowing, shows when each one earns its place, and covers the shared attributes that control validation, defaults, and the on-screen keyboard your mobile users see.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Choose the most appropriate
typefor each piece of data you collect - Use text, numeric, date/time, selection, and special input types correctly
- Apply validation attributes —
required,min/max,pattern,minlength/maxlength,step - Explain how input types change the mobile keyboard and improve completion rates
- Distinguish behavior attributes like
readonly,disabled,autofocus, andmultiple
Estimated Time: 35–45 minutes • Difficulty: Beginner
Hands-on: Build a validation-only registration form using HTML attributes and no JavaScript.
In This Lesson
One Element, Many Tools
The <input> element is the most versatile form control, and its type attribute is the dial that reshapes it. Change type and you change three things at once: the on-screen widget, the built-in validation, and — crucially on phones — the keyboard the device offers.
💡 A useful analogy: Input types are like specialized tools in a toolbox. You could tighten every screw with a plain text field, but reaching fortype="email",type="number", ortype="date"is like grabbing the right screwdriver — the job gets faster, the result is cleaner, and fewer mistakes slip through.
HTML5 dramatically expanded this list, moving work that once needed custom JavaScript — email checks, number spinners, date pickers — into the browser itself.
Text-Based Inputs
These all accept typed characters, but each carries semantic meaning and, in several cases, built-in validation.
| Type | What it's for | Built-in behavior |
|---|---|---|
text | Names, short free-form answers | The default; no validation |
password | Passwords, PINs | Masks the characters |
email | Email addresses | Checks for a valid email shape |
url | Web addresses | Checks for a valid URL shape |
tel | Phone numbers | No format enforced; pair with pattern |
search | Search boxes | Styling + a clear (✕) button |
<label for="email">Email address</label>
<input type="email" id="email" name="email" autocomplete="email" required>
<label for="website">Your website</label>
<input type="url" id="website" name="website" placeholder="https://example.com">
<label for="phone">Phone number</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" placeholder="123-456-7890">
💡 Why tel doesn't validate format
Phone formats vary wildly across the world, so type="tel" deliberately enforces nothing. Its real payoff is on mobile, where it summons a numeric dial pad. If you need a specific shape, add a pattern — but keep it forgiving of spaces, dashes, and country codes.
Numeric Inputs
type="number"
A field for exact numbers, usually with up/down spinner controls. Constrain it with min, max, and step.
<label for="quantity">Quantity</label>
<input type="number" id="quantity" name="quantity"
min="1" max="10" step="1" value="1">
type="range"
A slider for a value where the exact number matters less than the relative position.
<label for="volume">Volume</label>
<input type="range" id="volume" name="volume" min="0" max="100" step="1" value="50">
Analogy: Anumberinput is like typing an exact temperature into a thermostat; arangeinput is like sliding the dial and eyeballing "about warm enough."
Date & Time Inputs
These render native pickers so users never have to guess your preferred date format. All accept min/max to bound the selectable range.
| Type | Collects | Typical use |
|---|---|---|
date | Year-month-day | Date of birth, booking date |
time | Hours & minutes | Appointment slots |
datetime-local | Date + time (no timezone) | Event scheduling |
month | Month + year | Card expiry, monthly reports |
week | Week + year | Weekly planning |
<label for="birthday">Date of birth</label>
<input type="date" id="birthday" name="birthday" min="1900-01-01" max="2026-12-31">
<label for="expiry">Card expiry</label>
<input type="month" id="expiry" name="card_expiry">
Selection & Special Inputs
type="checkbox" — independent toggles
Each checkbox turns on or off on its own. Use them for "select all that apply" and single opt-ins.
<input type="checkbox" id="subscribe" name="subscribe" value="yes">
<label for="subscribe">Subscribe to the newsletter</label>
Analogy: Checkboxes are like light switches — each flips independently of the others.
type="radio" — one from a group
Radios that share a name form a mutually exclusive group: choosing one clears the rest. Always wrap a radio group in a <fieldset> with a <legend>.
<fieldset>
<legend>Shipping method</legend>
<input type="radio" id="standard" name="shipping" value="standard" checked>
<label for="standard">Standard</label>
<input type="radio" id="express" name="shipping" value="express">
<label for="express">Express</label>
</fieldset>
Analogy: Radio buttons are like the station presets on a car radio — pressing one pops the previously selected one out.
type="color", type="file", type="hidden"
<label for="theme">Theme color</label>
<input type="color" id="theme" name="theme_color" value="#3366ff">
<label for="avatar">Profile picture</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
<input type="hidden" name="user_id" value="12345">
⚠️ File inputs need the right form encoding
Any form containing type="file" must set method="post" and enctype="multipart/form-data" on the <form>, or the file won't upload. The accept attribute (e.g. image/*) hints which files the picker should show.
💡 Prefer <button> over <input type="submit">
Modern practice favors <button type="submit">Send</button> over <input type="submit"> because a <button> can contain markup — an icon, styled text — giving you far more design freedom. Reserve type="reset" buttons for rare cases; they too easily wipe out a user's work by accident.
Input Attributes
Beyond type, a handful of attributes appear on almost every input. Group them by what they do.
Core
name— the key the value is submitted under (required to be submitted at all)id— unique DOM identifier used by labels, CSS, and JavaScriptvalue— the initial or current valueplaceholder— a faint hint inside the field; never a replacement for a label
Validation
required— the field must be filled before the form submitsminlength/maxlength— character limits for textmin/max— value bounds for numbers, dates, and rangesstep— the increment for numeric and range inputspattern— a regular expression the value must match
Behavior
disabled— greyed out, not editable, and not submittedreadonly— not editable but still submittedautofocus— grabs focus on page load (use once per page, sparingly)multiple— allows several values (email and file inputs)autocomplete— pre-fill hints likeemailornew-password
📖 disabled vs readonly
Both stop the user from typing, but they differ where it counts: a disabled field is skipped entirely when the form submits, while a readonly field still sends its value. Reach for readonly when you want to show a locked-but-submitted value (like a pre-filled account number).
Mobile & Accessibility Payoffs
Choosing the right input type isn't just tidy — it measurably improves the experience, especially on phones, where the type determines the keyboard that pops up.
| Type | Mobile keyboard shown |
|---|---|
email | Adds @ and .com keys |
tel | Numeric dial pad |
number | Number-focused keypad |
url | Adds / and .com keys |
date | Native touch date picker |
✅ Small change, real impact
Swapping generic text fields for semantic types lowers friction and form abandonment. Semantic types also help screen readers announce a field's purpose, and browser validation catches errors before the user ever hits submit. A form that's easier for assistive-tech users is easier for everyone.
Worked Example: A Checkout Form
This condensed checkout puts several input types and validation attributes to work together. Read each field as a deliberate choice of the right tool.
<form action="/process-order" method="post">
<fieldset>
<legend>Contact</legend>
<label for="name">Full name</label>
<input type="text" id="name" name="full_name" autocomplete="name" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email" required>
<label for="phone">Phone</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" placeholder="123-456-7890">
</fieldset>
<fieldset>
<legend>Payment</legend>
<label for="card">Card number</label>
<input type="text" id="card" name="card_number"
inputmode="numeric" pattern="[0-9]{16}" maxlength="16" required>
<label for="expiry">Expiry</label>
<input type="month" id="expiry" name="card_expiry" required>
<label for="cvv">CVV</label>
<input type="text" id="cvv" name="cvv"
inputmode="numeric" pattern="[0-9]{3,4}" maxlength="4" required>
</fieldset>
<label for="qty">Quantity</label>
<input type="number" id="qty" name="quantity" min="1" max="10" value="1" required>
<button type="submit">Place order</button>
</form>
What the attributes buy you
The card and CVV fields use inputmode="numeric" for a numeric mobile keypad while staying type="text" (so leading zeros survive), plus pattern and maxlength to enforce shape. The required flags block submission of an incomplete order — no JavaScript needed.
Hands-on Exercise
🏋️ Validation With Attributes Only
Objective: Build a registration form whose rules are enforced entirely by HTML attributes — zero JavaScript.
Requirements:
- Username: text, 5–15 characters (
minlength/maxlength), required - Password: password, at least 8 characters, required
- Email: email type, required
- Age: number, between 18 and 120
- Terms: a required checkbox
Open it in the browser and try to submit with bad values — the browser should block you and explain why.
💡 Hint
Length limits use minlength/maxlength; numeric bounds use min/max. A checkbox marked required must be checked before the form will submit. Let the browser show its native validation bubble on submit.
✅ Sample solution
<form action="/register" method="post">
<label for="username">Username</label>
<input type="text" id="username" name="username"
minlength="5" maxlength="15" required>
<label for="password">Password</label>
<input type="password" id="password" name="password"
minlength="8" autocomplete="new-password" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
<label for="age">Age</label>
<input type="number" id="age" name="age" min="18" max="120" required>
<input type="checkbox" id="terms" name="terms" value="agreed" required>
<label for="terms">I accept the terms of service</label>
<button type="submit">Sign up</button>
</form>
Try submitting with a 3-character username or an age of 12 — the browser refuses and points at the offending field. That's HTML5 validation doing the work for free.
🎯 Quick Quiz
Question 1: You need users on phones to see a numeric dial pad when entering a phone number. Which type is the best fit?
Question 2: A field must be shown to the user but its value must still be submitted with the form. Which attribute do you use?
Question 3: Which set of attributes limits a number input to whole values from 1 to 10?
Summary & Quiz
🎉 Key Takeaways
- The
typeattribute reshapes one<input>into a specialized widget, validator, and mobile keyboard. - Prefer semantic types —
email,url,tel,number,date— over generic text. - Validation attributes (
required,min/max,pattern,minlength/maxlength) catch errors with no JavaScript. disableddrops a field from submission;readonlykeeps it. File inputs needmultipart/form-data.- Right-typing inputs improves mobile keyboards, accessibility, and completion rates at once.
📚 Further Reading
🚀 What's Next?
You've mastered the fields. Next we broaden the toolkit beyond <input> — the form controls and labels lesson covers <select>, <textarea>, <fieldset>, <datalist>, and the labeling patterns that make forms accessible.
🎉 Nice work!
You can now pick the perfect input type for any piece of data — and let the browser validate it for free.