input
The most versatile form element, accepting text, numbers, dates, files, and more through the type attribute. Always pair with a label for accessibility.
Input Type Overview
| Category | Types | Purpose |
|---|---|---|
| Text | text, email, password, url, tel, search |
Single-line text input |
| Numeric | number, range |
Numeric values with constraints |
| Date/Time | date, time, datetime-local, month, week |
Temporal values with pickers |
| Selection | checkbox, radio |
Boolean or mutually exclusive choices |
| Other | file, color, hidden |
Specialized inputs |
Text Input Types
Single-line text inputs for names, emails, passwords, URLs, phone numbers, and search. Each type triggers the appropriate mobile keyboard and built-in validation.
<input type="text" placeholder="Name" autocomplete="name" /><input type="email" placeholder="Email" autocomplete="email" /><input type="password" autocomplete="current-password" /><input type="url" placeholder="https://" /><input type="tel" placeholder="Phone" autocomplete="tel" /><input type="search" placeholder="Search..." />
Numeric Input Types
Use type="number" for values with increment/decrement controls, and type="range" for slider selection. Constrain values with min, max, and step.
<input type="number" min="1" max="99" step="1" value="1" /><input type="number" min="0" step="0.01" value="9.99" /><input type="range" min="0" max="100" value="50" />
Date and Time Input Types
Native date/time pickers vary by browser. Consider progressive enhancement. Use min and max to constrain date ranges.
<input type="date" /><input type="time" /><input type="datetime-local" /><input type="month" /><input type="week" /> <!-- With date constraints --><input type="date" min="2024-01-01" max="2024-12-31" />
Checkbox and Radio Inputs
Use type="checkbox" for boolean or multi-select choices, and type="radio" for mutually exclusive selections within a group (same name). Always wrap radio groups in a fieldset for accessibility.
<!-- Checkbox --><label> <input type="checkbox" name="subscribe" /> Subscribe to newsletter</label> <!-- Radio group (wrap in fieldset) --><fieldset> <legend>Select size</legend> <label> <input type="radio" name="size" value="small" /> Small </label> <label> <input type="radio" name="size" value="medium" checked /> Medium </label> <label> <input type="radio" name="size" value="large" /> Large </label></fieldset>
Other Input Types
type="file"
File upload. Use accept to restrict file types and multiple for multiple files. See also the data-upload enhancement below.
type="color"
Color picker returning a hex value. See also the data-color enhancement below.
type="hidden"
Invisible form data. Used for tokens, IDs, or tracking.
<input type="hidden" name="csrf_token" value="abc123" /><input type="hidden" name="user_id" value="42" />
<input type="file" accept=".pdf,.doc" /><input type="file" accept="image/*" multiple /input type="color" value="#4a90d9" /><input type="hidden" name="token" value="..." />
Input States
Inputs support disabled, readonly, required, and invalid states. Disabled inputs prevent interaction and are not submitted with the form. Readonly inputs allow selection but not editing, and their values are submitted.
<input type="text" disabled value="Cannot edit" /><input type="text" readonly value="Can select but not edit" /> <!-- Required --><input type="text" required /> <!-- Invalid state --><input type="email" aria-invalid="true" value="not-an-email" /> <!-- Pattern validation --><input type="text" pattern="[a-zA-Z0-9_]+" title="Letters, numbers, and underscores only" />
Validation Attributes
| Attribute | Purpose | Example |
|---|---|---|
required |
Field must have a value | <input required /> |
minlength |
Minimum character count | minlength="2" |
maxlength |
Maximum character count | maxlength="100" |
min |
Minimum numeric/date value | min="0" |
max |
Maximum numeric/date value | max="100" |
step |
Increment for numeric values | step="0.01" |
pattern |
Regex pattern for validation | pattern="[A-Za-z]+" |
type |
Built-in validation (email, url) | type="email" |
With Datalist
Add autocomplete suggestions using datalist.
<input type="text" list="browsers" /><datalist id="browsers"> <option value="Chrome"></option> <option value="Firefox"></option></datalist>
With form-field
Use the form-field custom element for CSS-only validation feedback.
<form-field> <label for="ff-email">Email</label> <input type="email" id="ff-email" name="email" required autocomplete="email" aria-describedby="ff-email-msg" /> <output id="ff-email-msg" for="ff-email" aria-live="polite"> Enter a valid email address </output></form-field>
Autocomplete Attribute
Help browsers autofill forms correctly with specific autocomplete values.
| Field Type | Autocomplete Value |
|---|---|
| Full name | name |
email |
|
| Phone | tel |
| Street address | street-address |
| City | address-level2 |
| State/Province | address-level1 |
| Postal code | postal-code |
| Country | country-name |
| Credit card number | cc-number |
| Current password | current-password |
| New password | new-password |
| One-time code | one-time-code |
<input type="text" name="name" autocomplete="name" /><input type="email" name="email" autocomplete="email" /><input type="password" autocomplete="current-password" /><input type="password" autocomplete="new-password" />
Toggle Switch (data-switch)
Add data-switch to a checkbox for on/off toggle switch styling. Uses CSS appearance: none with a sliding knob. JS adds role="switch" for screen readers.
<!-- Small --><label> <input type="checkbox" data-switch="sm" name="compact"> Compact mode</label> <!-- Default --><label> <input type="checkbox" data-switch name="default"> Default size</label> <!-- Large --><label> <input type="checkbox" data-switch="lg" name="feature"> Large switch</label>
| Attribute | Values | Description |
|---|---|---|
data-switch |
"", "sm", "lg" |
Enable switch styling with optional size variant. |
Password Strength (data-strength)
Add data-strength and data-rules to a password input inside <form-field> to show a real-time strength meter and rules checklist. Works alongside the existing password show/hide toggle.
<form-field> <label for="pw">Password</label> <input type="password" id="pw" data-strength data-rules="length:8,uppercase,lowercase,number,special" placeholder="Create a strong password" autocomplete="new-password" /></form-field>
| Attribute | Description |
|---|---|
data-strength |
Enable strength meter and rules checklist. |
data-rules |
Comma-separated rules: length:N, uppercase, lowercase, number, special. |
Strength Levels
- Weak — Less than 40% of rules met
- Fair — 40–74% of rules met
- Good — 75–99% of rules met
- Strong — All rules met
Range Enhancement (data-range)
Add data-range to a range input for cross-browser styled track and thumb. Add data-bubble for a floating value display. Pair with <datalist> for tick labels.
<input type="range" min="0" max="1000" step="100" list="prices" data-range data-bubble data-prefix="$"><datalist id="prices"> <option value="0" label="$0"> <option value="500" label="$500"> <option value="1000" label="$1K"></datalist>
| Attribute | Description |
|---|---|
data-range |
Enable cross-browser track/thumb styling and fill. |
data-bubble |
Show floating value bubble above the thumb. |
data-prefix |
Text before the value (e.g., "$"). |
data-suffix |
Text after the value (e.g., "%", "°F"). |
File Upload Zone (data-upload)
Add data-upload to a file input to wrap it in a drag-and-drop zone with file list display.
<input type="file" data-upload accept=".pdf,.doc" multiple>
| Attribute | Description |
|---|---|
data-upload |
Enable drop zone enhancement on a file input. |
The native accept and multiple attributes work as normal. Without JS, the standard file input is shown.
Input Masking (data-mask)
Add data-mask to a text input to format the value as the user types. Preset masks handle common patterns; use data-mask="custom" with data-pattern for arbitrary formats.
<!-- Preset masks --><input type="text" data-mask="phone" placeholder="(555) 123-4567"><input type="text" data-mask="credit-card" placeholder="1234 5678 9012 3456"><input type="text" data-mask="date" placeholder="MM/DD/YYYY"><input type="text" data-mask="ssn" placeholder="123-45-6789"><input type="text" data-mask="zip" placeholder="12345"> <!-- Custom mask: # = digit, A = letter, * = any --><input type="text" data-mask="custom" data-pattern="AA-####" placeholder="AB-1234">
Preset Masks
| Value | Pattern | Example |
|---|---|---|
phone | (###) ###-#### | (555) 123-4567 |
credit-card | #### #### #### #### | 1234 5678 9012 3456 |
date | ##/##/#### | 01/15/2026 |
ssn | ###-##-#### | 123-45-6789 |
zip | ##### | 90210 |
Custom Mask Tokens
| Token | Accepts |
|---|---|
# | Any digit (0-9) |
A | Any letter (a-z, A-Z) |
* | Any alphanumeric character |
Attributes
| Attribute | Description |
|---|---|
data-mask | Mask type: phone, credit-card, date, ssn, zip, or custom. |
data-pattern | Custom pattern string when data-mask="custom". |
Behavior
- Auto-sets
inputmode="numeric"for digit-only masks - Auto-sets
maxlengthfrom the pattern length - Stores the unformatted value in
dataset.rawValuefor form processing - Without JS, the input works as a standard text field
Range Markers (data-markers)
Add data-markers to a data-range input to display tick marks at each step value. Combines with data-bubble and <datalist> labels.
<input type="range" min="1" max="5" step="1" value="3" data-range data-bubble data-markers>
| Attribute | Description |
|---|---|
data-markers |
Show tick marks at each step position along the track. |
Toggle Tags (data-toggle-tags)
Wrap checkboxes in a <fieldset data-toggle-tags> for pill-chip styling. Pure CSS — no JS needed. Add data-max to limit the number of selections.
<fieldset data-toggle-tags> <legend>Favorite Topics</legend> <label><input type="checkbox" name="topics" value="ai"> AI / ML</label> <label><input type="checkbox" name="topics" value="web"> Web Dev</label> <label><input type="checkbox" name="topics" value="mobile"> Mobile</label></fieldset> <!-- With max selection limit --><fieldset data-toggle-tags data-layout-max="3"> <legend>Pick up to 3</legend> <label><input type="checkbox" name="skills" value="js"> JavaScript</label> <label><input type="checkbox" name="skills" value="py"> Python</label> <label><input type="checkbox" name="skills" value="go"> Go</label> <label><input type="checkbox" name="skills" value="rust"> Rust</label></fieldset>
| Attribute | Description |
|---|---|
data-toggle-tags |
Enable pill-chip styling on a checkbox fieldset. |
data-max |
Maximum number of selections. Unchecked boxes are disabled at the limit. |
Why CSS-Only
Native checkboxes give you form participation, validation, reset, keyboard navigation, and accessibility for free. The visual transformation uses :has(:checked) to style labels. JS is only loaded when data-max is set.
Number Stepper (data-stepper)
Add data-stepper to a number input for custom +/− buttons. Hides native spinners and disables buttons at min/max boundaries.
<input type="number" min="0" max="50" step="1" value="1" data-stepper> <!-- Decimal steps --><input type="number" min="0" max="10" step="0.5" value="1.0" data-stepper>
| Attribute | Description |
|---|---|
data-stepper |
Enable +/− stepper buttons on a number input. |
Without JS, the native number input with browser spinners works fine.
Enhanced Color Input (data-color)
Add data-color to a color input for a styled swatch circle and hex code display. Clicking opens the native color picker.
<input type="color" value="#6366f1" data-color>
| Attribute | Description |
|---|---|
data-color |
Enable swatch + hex display enhancement on a color input. |
Without JS, the native color picker renders (functional but unstyled).
Accessibility Notes
- Always use labels: Every input needs an associated label
- Use autocomplete: Helps users fill forms faster and more accurately
- Provide error messages: Use
aria-describedbyto link error text to inputs - Mark invalid fields: Use
aria-invalid="true"for explicit invalid state - Avoid placeholder as label: Placeholders disappear when typing
- Visible focus: Don't remove focus outlines
- Touch targets: Minimum 44x44px for checkboxes and radios
- Fieldsets for radio groups: Always wrap radio groups in fieldset
CSS Reference
/* Form control tokens (defined in src/tokens/forms.css) */:root { --input-height: var(--size-touch-min); --input-padding-inline: var(--size-s); --input-bg: var(--color-surface); --input-border: var(--color-border); --input-border-focus: var(--color-interactive); --input-radius: var(--radius-m); --input-text: inherit; --input-placeholder: var(--color-text-muted); --control-size: 1.125rem; --control-border: var(--color-border-strong); --control-checked-bg: var(--color-primary); --control-checked-border: var(--color-primary); --control-radius-check: var(--radius-s); --control-radius-radio: var(--radius-full); --select-chevron: url("data:image/svg+xml,..."); --range-track-h: 0.375rem; --range-track-bg: var(--color-border); --range-track-fill: var(--color-primary); --range-thumb-size: 1.25rem; --range-thumb-bg: var(--color-surface); --range-thumb-border: var(--color-primary);} /* Text inputs, select, textarea — token-driven */input:not(:is([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="submit"], [type="button"], [type="reset"])),textarea, select { border: var(--border-width-thin) solid var(--input-border); border-radius: var(--input-radius); background: var(--input-bg); color: var(--input-text); min-block-size: var(--input-height);} /* Checkbox & radio — appearance: none + pseudo-elements */input[type="checkbox"]:not([data-switch]),input[type="radio"] { appearance: none; width: var(--control-size); height: var(--control-size); border: var(--border-width-medium) solid var(--control-border);} input[type="checkbox"]:not([data-switch]):checked,input[type="radio"]:checked { background: var(--control-checked-bg); border-color: var(--control-checked-border);} /* Checkmark via clip-path (zero SVG assets) */input[type="checkbox"]:not([data-switch]):checked::after { clip-path: polygon(14% 50%, 8% 60%, 38% 86%, 94% 20%, 86% 12%, 38% 70%);} /* Radio dot */input[type="radio"]:checked::after { inset: 3px; border-radius: 50%;} /* Range — token-driven track and thumb */input[type="range"] { appearance: none; background: linear-gradient(to right, var(--range-track-fill) var(--_pct, 50%), var(--range-track-bg) var(--_pct, 50%));}
Related
- label - Essential for accessibility
- form - Container for inputs
- datalist - Autocomplete suggestions
- fieldset - Group related inputs (especially radios)
- textarea - Multi-line text input
- select - Dropdown selection
- form-field - Enhanced form field with validation
- combo-box - Searchable dropdown with filtering
- data-table - Sortable, filterable data with input controls
- dialog - Modal forms via
method="dialog"