Skip to content

HTML Input Types

The element is incredibly versatile. Its behavior and appearance change dramatically based on its type attribute. This chapter explores the most common and useful input types.

Modern web forms rely heavily on using the correct input types for better user experience, accessibility, and built-in browser validation.

<input type="text"> defines a single-line text input field. This is the default type if no type is specified.

Best Practice: Always pair your inputs with a <label> element for accessibility. The label’s for attribute should match the input’s id.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Text Input Example</title>
<style>
label {
display: block;
margin-bottom: 5px;
}
input[type="text"] {
margin-bottom: 10px;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
</style>
</head>
<body>
<form>
<label for="fname">First name:</label>
<input type="text" id="fname" name="firstname">
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lastname">
</form>
</body>
</html>

Common attributes: placeholder, required, minlength, maxlength, pattern (for specific format validation using regular expressions).

<input type="password"> defines a password field. Characters entered are masked (shown as asterisks or dots) for security.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Password Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<label for="pwd">Password:</label>
<input type="password" id="pwd" name="password" required minlength="8">
</form>
</body>
</html>

Note: While the input is masked visually, the data is sent as plain text unless the form is submitted over HTTPS. Always use HTTPS for sensitive data.

<input type="submit"> defines a button for submitting the form data to a server-side handler.

The form handler’s URL is specified in the <form> element’s action attribute, and the HTTP method (usually GET or POST) is specified in the method attribute.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Submit Button Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input[type="text"] { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
input[type="submit"] { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
input[type="submit"]:hover { background-color: #0056b3; }
</style>
</head>
<body>
<form action="/process-form" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="user_email" required>
<input type="submit" value="Sign Up">
</form>
</body>
</html>

The value attribute sets the text displayed on the button. If omitted, the browser displays a default value like “Submit”. Consider using the <button type="submit"> element for more styling flexibility.

<input type="radio"> defines a radio button. Radio buttons allow a user to select only one option from a group.

All radio buttons in a group must share the same name attribute. Use the checked attribute to pre-select an option.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Radio Button Example</title>
<style> /* Basic styling */
fieldset { border: 1px solid #ccc; padding: 15px; margin-bottom: 10px; }
legend { font-weight: bold; }
label { margin-right: 15px; }
</style>
</head>
<body>
<form>
<fieldset>
<legend>Choose your preferred contact method:</legend>
<input type="radio" id="contact_email" name="contact_method" value="email" checked>
<label for="contact_email">Email</label>
<input type="radio" id="contact_phone" name="contact_method" value="phone">
<label for="contact_phone">Phone</label>
<input type="radio" id="contact_mail" name="contact_method" value="mail">
<label for="contact_mail">Mail</label>
</fieldset>
</form>
</body>
</html>

Using <fieldset> and <legend> improves structure and accessibility for groups of related controls.

<input type="checkbox"> defines a checkbox. Checkboxes allow a user to select zero or more options from a list.

Each checkbox typically has a unique value. Checkboxes sharing the same name can be processed as a group on the server.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Checkbox Example</title>
<style> /* Basic styling */
fieldset { border: 1px solid #ccc; padding: 15px; margin-bottom: 10px; }
legend { font-weight: bold; }
label { display: block; margin-bottom: 5px; }
</style>
</head>
<body>
<form>
<fieldset>
<legend>Select your interests:</legend>
<input type="checkbox" id="interest_music" name="interests[]" value="music">
<label for="interest_music">Music</label>
<input type="checkbox" id="interest_sports" name="interests[]" value="sports" checked>
<label for="interest_sports">Sports</label>
<input type="checkbox" id="interest_tech" name="interests[]" value="technology">
<label for="interest_tech">Technology</label>
</fieldset>
</form>
</body>
</html>

Note: Using name="interests[]" is a common convention (especially with PHP) to signal that multiple values for ‘interests’ might be submitted.

<input type="button"> defines a generic button. It has no default behavior (unlike type="submit" or type="reset").

These buttons are typically used with JavaScript to trigger custom actions.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Button Input Example</title>
<style> /* Basic styling */
input[type="button"] { padding: 10px 15px; background-color: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer; }
input[type="button"]:hover { background-color: #5a6268; }
</style>
</head>
<body>
<input type="button" value="Show Message" onclick="alert('Hello World!')">
<script>
// Modern approach: Attach event listeners via JavaScript
// const myButton = document.getElementById('myCustomButton');
// myButton.addEventListener('click', () => {
// alert('Button clicked!');
// });
</script>
<!-- <input type="button" id="myCustomButton" value="Click Me (JS)"> -->
</body>
</html>

While onclick works, attaching event listeners using JavaScript (addEventListener) is generally preferred for better separation of concerns.

HTML5 introduced several new input types that improve user experience and enable better validation:

  • color
  • date
  • datetime-local
  • email
  • month
  • number
  • range
  • search
  • tel
  • time
  • url
  • week
  • file

Browsers provide specialized UI controls (like date pickers, color pickers, sliders) and validation for these types. If a browser doesn’t support a specific type, it typically falls back to displaying it as type="text".

<input type="number"> is used for fields that should contain a numeric value. Browsers may display spinner controls.

Attributes like min, max, and step allow setting restrictions on the acceptable range and increments.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Number Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="quantity">Quantity (between 1 and 10):</label>
<input type="number" id="quantity" name="quantity" min="1" max="10" value="1">
<label for="rating">Rating (0 to 5, steps of 0.5):</label>
<input type="number" id="rating" name="rating" min="0" max="5" step="0.5">
</form>
</body>
</html>

<input type="date"> provides a control for selecting a date (year, month, day). Most browsers display a date picker.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Date Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="birthdate">Birth Date:</label>
<input type="date" id="birthdate" name="birthdate">
<label for="startdate">Project Start (after 2024-01-01):</label>
<input type="date" id="startdate" name="startdate" min="2024-01-02">
<label for="enddate">Project End (before 2025-01-01):</label>
<input type="date" id="enddate" name="enddate" max="2024-12-31">
</form>
</body>
</html>

The date format displayed depends on the browser and OS locale, but the submitted value is standardized (YYYY-MM-DD).

<input type="color"> provides a UI for selecting a color. Browsers typically show a color picker.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Color Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input[type="color"] { vertical-align: middle; width: 50px; height: 30px; padding: 0; border: none; }
</style>
</head>
<body>
<form>
<label for="favcolor">Select your favorite color:</label>
<input type="color" id="favcolor" name="favcolor" value="#ff0000"> <!-- Default to red -->
</form>
</body>
</html>

The submitted value is a hexadecimal color code (e.g., #RRGGBB).

<input type="range"> defines a control for entering a number whose exact value is not critical. Browsers typically display it as a slider.

Use min, max, step, and value attributes to configure the slider.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Range Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input[type="range"] { width: 200px; }
</style>
</head>
<body>
<form oninput="output.value=volume.value">
<label for="volume">Volume:</label>
<input type="range" id="volume" name="volume" min="0" max="100" value="50" step="1">
<output name="output" for="volume">50</output>
</form>
</body>
</html>

Consider adding an <output> element or using JavaScript to display the current value, as sliders aren’t always precise.

<input type="email"> is used for fields that should contain an email address.

Browsers provide basic validation for the email format on submission. Mobile devices often show a specialized keyboard.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Email Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; width: 250px; }
</style>
</head>
<body>
<form>
<label for="user_email">Enter your email:</label>
<input type="email" id="user_email" name="user_email" placeholder="you@example.com" required>
</form>
</body>
</html>

The multiple attribute allows entering a comma-separated list of email addresses.

<input type="tel"> is used for fields that should contain a telephone number.

Unlike email or url, tel does not enforce a specific format, because phone number formats vary widely globally. Its main benefit is triggering numeric-optimized keyboards on mobile devices.

Use the pattern attribute with a regular expression for specific format validation.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Telephone Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="phone">Phone Number (Format: 123-456-7890):</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
placeholder="123-456-7890" required>
</form>
</body>
</html>

<input type="url"> is used for fields that should contain a URL address.

Browsers perform basic validation for the URL format (requiring something like scheme://...). Mobile devices may offer URL-specific keyboard shortcuts.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>URL Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; width: 300px; }
</style>
</head>
<body>
<form>
<label for="homepage">Add your homepage URL:</label>
<input type="url" id="homepage" name="homepage"
placeholder="https://example.com" required>
</form>
</body>
</html>

Similar to date, HTML5 offers more granular time inputs:

  • datetime-local: Select date and time (no timezone). Replaced the deprecated datetime type.
  • month: Select month and year.
  • week: Select week and year.
  • time: Select time (hour, minute, seconds; no timezone).

These typically render specialized controls in supporting browsers.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Time Inputs Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="meeting-time">Meeting Time:</label>
<input type="datetime-local" id="meeting-time" name="meeting-time">
<label for="start-month">Project Start Month:</label>
<input type="month" id="start-month" name="start-month">
<label for="delivery-week">Delivery Week:</label>
<input type="week" id="delivery-week" name="delivery-week">
<label for="alarm-time">Alarm Time:</label>
<input type="time" id="alarm-time" name="alarm-time">
</form>
</body>
</html>

<input type="search"> is intended for search fields. Functionally, it behaves like type="text", but browsers might style it differently (e.g., rounded corners) or add a clear button.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<form>
<label for="site-search">Search this site:</label>
<input type="search" id="site-search" name="query">
<button type="submit">Search</button>
</form>
</body>
</html>

<input type="file"> allows the user to select one or more files from their device storage. Browsers render a button and text indicating the selection status.

Use the accept attribute to suggest file types (e.g., accept="image/*", accept=".pdf,.docx"). The multiple attribute allows selecting multiple files.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Input Example</title>
<style> /* Basic styling */
label { display: block; margin-bottom: 5px; }
input { margin-bottom: 10px; }
</style>
</head>
<body>
<!-- Remember to set enctype="multipart/form-data" on the form -->
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="avatar">Upload Profile Picture (JPEG/PNG):</label>
<input type="file" id="avatar" name="avatar" accept="image/jpeg, image/png">
<label for="docs">Upload Documents (PDF/DOCX):</label>
<input type="file" id="docs" name="documents[]" accept=".pdf,.docx" multiple>
<button type="submit">Upload</button>
</form>
</body>
</html>

Important: For file uploads to work, the form’s method must be post and the enctype attribute must be set to multipart/form-data.

HTML5 provides attributes for client-side validation, improving user experience by catching errors before submission:

AttributeDescription
requiredSpecifies that the input field must be filled out before submitting.
patternSpecifies a regular expression the input value must match.
min / maxSpecifies the minimum and maximum allowed values (for numeric, date, time, range types).
stepSpecifies the legal number intervals (for numeric, date, time, range types).
minlength / maxlengthSpecifies the minimum and maximum number of characters (for text, email, search, password, tel, url).
disabledSpecifies that an input field should be disabled (uneditable and not submitted).
readonlySpecifies that an input field cannot be changed, but its value is still submitted.
placeholderProvides a hint to the user about what to enter (disappears on focus/input).

While helpful, client-side validation should always be complemented by server-side validation for security.