Skip to main content

🎛️ 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 type for 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, and multiple

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 for type="email", type="number", or type="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.

flowchart LR A["<input type=?>"] --> B[Text family] A --> C[Numeric family] A --> D[Date & time family] A --> E[Selection family] A --> F[Special: file, hidden] B --> B1["text · email · url · tel · search · password"] C --> C1["number · range"] D --> D1["date · time · datetime-local · month · week"] E --> E1["checkbox · radio · color"]

Text-Based Inputs

These all accept typed characters, but each carries semantic meaning and, in several cases, built-in validation.

TypeWhat it's forBuilt-in behavior
textNames, short free-form answersThe default; no validation
passwordPasswords, PINsMasks the characters
emailEmail addressesChecks for a valid email shape
urlWeb addressesChecks for a valid URL shape
telPhone numbersNo format enforced; pair with pattern
searchSearch boxesStyling + 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: A number input is like typing an exact temperature into a thermostat; a range input 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.

TypeCollectsTypical use
dateYear-month-dayDate of birth, booking date
timeHours & minutesAppointment slots
datetime-localDate + time (no timezone)Event scheduling
monthMonth + yearCard expiry, monthly reports
weekWeek + yearWeekly 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 JavaScript
  • value — the initial or current value
  • placeholder — a faint hint inside the field; never a replacement for a label

Validation

  • required — the field must be filled before the form submits
  • minlength / maxlength — character limits for text
  • min / max — value bounds for numbers, dates, and ranges
  • step — the increment for numeric and range inputs
  • pattern — a regular expression the value must match

Behavior

  • disabled — greyed out, not editable, and not submitted
  • readonly — not editable but still submitted
  • autofocus — grabs focus on page load (use once per page, sparingly)
  • multiple — allows several values (email and file inputs)
  • autocomplete — pre-fill hints like email or new-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.

TypeMobile keyboard shown
emailAdds @ and .com keys
telNumeric dial pad
numberNumber-focused keypad
urlAdds / and .com keys
dateNative 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 type attribute 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.
  • disabled drops a field from submission; readonly keeps it. File inputs need multipart/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.