Skip to content

Input Types

Modern HTML provides specialized input types that offer native pickers, mobile keyboard optimization, and built-in validation.

<input type="text" id="date" placeholder="YYYY-MM-DD">
<script src="datepicker-library.js"></script>
<script>
new DatePicker('#date', { format: 'YYYY-MM-DD' });
</script>
<input type="text" id="color" placeholder="#000000">
<script src="color-picker.js"></script>
<script>
new ColorPicker('#color');
</script>

Problems:

  • Large JavaScript library dependencies
  • Inconsistent UX across sites
  • No mobile optimization
  • Must implement validation separately
<input type="date" id="date">
<input type="color" id="color">

Benefits:

  • Native OS/browser pickers
  • Mobile keyboard optimization
  • Built-in validation
  • Zero dependencies
<!-- Date picker -->
<input type="date" name="date" value="2025-01-15">
<!-- Time picker -->
<input type="time" name="time" value="14:30">
<!-- Date and time -->
<input type="datetime-local" name="datetime" value="2025-01-15T14:30">
<!-- Month picker -->
<input type="month" name="month" value="2025-01">
<!-- Week picker -->
<input type="week" name="week" value="2025-W03">

With constraints:

<input
type="date"
name="appointment"
min="2025-01-01"
max="2025-12-31"
required
>
<input type="color" name="color" value="#3b82f6">

With datalist for suggestions:

<input type="color" name="color" list="colors">
<datalist id="colors">
<option value="#ef4444">
<option value="#3b82f6">
<option value="#22c55e">
</datalist>
<input type="range" name="volume" min="0" max="100" value="50" step="10">

With output display:

<label>
Volume:
<input
type="range"
name="volume"
min="0"
max="100"
value="50"
oninput="this.nextElementSibling.value = this.value"
>
<output>50</output>
</label>
<input type="number" name="quantity" min="1" max="99" step="1" value="1">

For decimals:

<input type="number" name="price" min="0" step="0.01" placeholder="0.00">
<input type="email" name="email" required placeholder="user@example.com">
<!-- Multiple emails -->
<input type="email" name="emails" multiple placeholder="Comma-separated emails">
<input type="url" name="website" placeholder="https://example.com">
<input type="tel" name="phone" placeholder="123-456-7890" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}">

Note: type="tel" doesn’t validate format (phone formats vary globally). Use pattern for validation.

<input type="search" name="query" placeholder="Search...">

Features:

  • Clear button in some browsers
  • Search-specific keyboard on mobile
  • Can trigger search history
TypeMobile Keyboard
textStandard keyboard
emailKeyboard with @ and .com
telNumeric phone pad
urlKeyboard with / and .com
numberNumeric keyboard
searchKeyboard with search button

Additional attributes for keyboard hints:

<!-- Numeric input (not type="number") -->
<input type="text" inputmode="numeric" pattern="[0-9]*">
<!-- Decimal numbers -->
<input type="text" inputmode="decimal">
<!-- Email without validation -->
<input type="text" inputmode="email">

Control the virtual keyboard without changing input type:

inputmodeKeyboard
noneNo keyboard
textStandard text
decimalNumbers with decimal
numericNumbers only
telPhone pad
searchSearch keyboard
emailEmail keyboard
urlURL keyboard
/* Custom date input */
input[type="date"] {
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
/* Style the calendar icon (WebKit) */
input[type="date"]::-webkit-calendar-picker-indicator {
cursor: pointer;
filter: invert(0.5);
}
/* Custom range slider */
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 8px;
background: #ddd;
border-radius: 4px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: #3b82f6;
border-radius: 50%;
cursor: pointer;
}
/* Custom color input */
input[type="color"] {
-webkit-appearance: none;
width: 50px;
height: 50px;
border: none;
cursor: pointer;
}
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: 2px solid #ccc;
border-radius: 4px;
}
TypeSupport
email, url, tel, search, number, rangeAll modern browsers
date, time, datetime-local, month, weekAll modern browsers
colorAll modern browsers

Safari had limited date/time support until Safari 14.1 (2021).

  • Native inputs are keyboard accessible
  • Screen readers announce input type
  • Error messages are announced
  • Mobile users get appropriate keyboards
  • Use <label> elements properly
<label for="birthday">Birthday</label>
<input type="date" id="birthday" name="birthday">
<!-- Or wrap the input -->
<label>
Birthday
<input type="date" name="birthday">
</label>

Use native input types when:

  • Built-in validation is sufficient
  • Native pickers are acceptable
  • You want mobile keyboard optimization
  • Reducing JavaScript is a priority

Consider JavaScript alternatives when:

  • You need a custom date format display
  • Native picker doesn’t match design requirements
  • You need date ranges or advanced features
  • Supporting specific legacy browsers