Input fields
Input fields turn curiosity into structured data—names, search terms, shipping details, or dates that steer the experience forward. Well-crafted fields hint at their expected content through labels, placeholders, and validation, reducing friction so people can stay focused on the task at hand rather than deciphering the UI.
The patterns below cover single-line inputs, selects, textareas, and enhanced combinations with icons, buttons, or suggestions. Use them as building blocks when designing flows: align labels, reuse helper text styles, and lean on the provided states to keep every form clear, accessible, and predictable from start to submit.
Text fields
Text inputs handle everything from simple strings to structured data types like email, tel, and date pickers. Pair each input with a descriptive label and keep placeholders instructional rather than essential, since helper text and validation states can communicate formatting rules far more reliably.
Connect every label via the for/id relationship, and avoid removing native browser affordances (e.g., numeric spinners) so keyboard, touch, and assistive users all benefit from the built-in semantics.
<input type="text">
<input type="text" disabled>
<input type="text" readonly>
<input type="text" required>
<input type="password">
<input type="tel">
<input type="email">
<input type="url">
<input type="search">
<input type="date">
<input type="time">
<input type="datetime-local">
<input type="week">
<input type="month">
<input type="number">
Select fields
Select elements constrain choices to a known list, perfect for states, categories, or filters where free-form entry would introduce errors. Rely on the native single-select for concise menus and the multiple variant when users need to select several items without leaving the form context.
Help messages where appropriate.
Keep option labels short and unique so they truncate gracefully, and always provide an empty first option or placeholder when a selection is optional. This ensures assistive tech can announce whether a value has been chosen, preventing accidental defaults.
<select>
<option value="...">...</option>
<option value="...">...</option>
<option value="...">...</option>
</select>
<select disabled>...</select>
<select multiple>
<option value="...">...</option>
<option value="...">...</option>
<option value="...">...</option>
</select>
<select disabled multiple>...</select>
Textarea
Textareas support longer narratives like feedback, descriptions, or multi-line code snippets. Keep them vertically resizable when possible and pair them with helper text describing content expectations so users can gauge the appropriate length.
Preserve line breaks server-side and mirror them in previews, and ensure disabled or read-only states still contrast enough with the background so the content remains legible.
<textarea></textarea>
<textarea disabled></textarea>
Attached labels
Attached labels keep inline units, suffixes, or prefixes tightly coupled to their fields. Use them for currency symbols, measurement units, or quick descriptors when a traditional block label would consume too much vertical space.
Reuse real <label> elements, even for inline adornments, so assistive technologies announce the association. When the label mirrors a unit (like “kg”), keep it short and avoid duplicating the same text inside the input value to prevent redundancy.
<div class="group">
<input type="text">
<label for="...">Appended label</label>
</div>
<div class="group">
<label for="...">Prepended label</label>
<input type="text">
</div>
<div class="group">
<select>...</select>
<label for="...">Appended label</label>
</div>
Icons
Icon adornments provide visual hints for expected content—mail icons for email fields, magnifiers for search, warning badges for validation. They also help users scan dense forms by reinforcing intent before they read the full label.
Ensure icons are decorative by default (hide them from screen readers) unless they convey critical meaning, and keep padding symmetrical so focus rings never clip against the SVG container.
<div class="group">
<input type="text" class="append-icon">
<svg class="icon">...</svg>
</div>
<div class="group">
<svg class="icon">...</svg>
<input type="text" class="prepend-icon">
</div>
<div class="group">
<svg class="icon">...</svg>
<input type="text" class="prepend-icon append-icon">
<svg class="icon">...</svg>
</div>
<div class="group">
<select class="append-icon">...</select>
<svg class="icon">...</svg>
</div>
Mixed
Mixed groups combine labels, icons, multiple inputs, and buttons to build compact flows like newsletter subscriptions or billing forms. Treat each grouping as a mini-layout: align baselines, reuse spacing tokens, and keep the reading order logical so both visual and assistive users can parse the sequence.
<div class="group">
<label for="..."><svg class="icon">...</svg></label>
<svg class="icon">...</svg>
<input type="email" class="prepend-icon">
<button class="primary">...</button>
<button class="secondary"><svg class="icon">...</svg></button>
</div>
<div class="group">
<input type="text">
<input type="text">
<button>...</button>
</div>
<div class="group">
<label for="..."><svg class="icon">...</svg></label>
<svg class="icon">...</svg>
<select class="prepend-icon">...</select>
<button class="primary">...</button>
<button class="secondary"><svg class="icon">...</svg></button>
</div>
<div class="group">
<select>...</select>
<select>...</select>
<button>...</button>
</div>
File upload
Under construction!
<input type="file" id="...">
<label for="...">...</label>
Suggestions
Suggestion panels pair an input with contextual results, ideal for autocomplete, search-as-you-type, or quick-pick lists. Panels can appear below or above the control, and the group variants show how icons, buttons, and stacked inputs keep the affordance cohesive even as the interaction grows richer.
Link the panel and input with aria-controls and aria-expanded so assistive tech understands when results appear, and keep keyboard navigation consistent (arrow keys to traverse, Enter to confirm) to build muscle memory.
<div class="suggestions">
<input type="...">
<div class="panel">...</div>
</div>
<div class="suggestions top">
<input type="...">
<div class="panel">...</div>
</div>
<div class="suggestions">
<div class="group"></div>
<div class="panel">...</div>
</div>