Input <input>
Inputs let users enter and edit text, numbers, dates, and other single-line values.
<input><l-form-field>
<label>Email</label>
<input
type="email"
placeholder="jane@acme.com"
/>
<p class="l-hint">We'll never share it.</p>
</l-form-field>l-form-field auto-styles a bare text <input> and wires the accessibility (label, hint, error, aria-*). Standalone, apply .l-input to the input yourself.
Options
Type
.l-input styles every text-like type. date and time get a custom picker icon; search gets a custom clear button — all with zero JavaScript.
Code
<div class="grid gap-4 max-w-sm">
<l-form-field>
<label>Text</label>
<input
type="text"
placeholder="Placeholder text"
/>
</l-form-field>
<l-form-field>
<label>Number</label>
<input
type="number"
placeholder="Placeholder text"
/>
</l-form-field>
<l-form-field>
<label>Password</label>
<input
type="password"
value="supersecret"
/>
</l-form-field>
<l-form-field>
<label>Date</label>
<input type="date" />
</l-form-field>
<l-form-field>
<label>Time</label>
<input type="time" />
</l-form-field>
<l-form-field>
<label>Search</label>
<input
type="search"
value="This a value"
/>
</l-form-field>
</div>States
Native disabled and readonly. Invalid is styled via :user-invalid (after interaction) or by setting aria-invalid="true" — inside l-form-field this is managed for you.
Enter a valid email address.
Code
<div class="grid gap-4 max-w-sm">
<l-form-field>
<label>Default</label>
<input
type="text"
placeholder="Placeholder text"
/>
</l-form-field>
<l-form-field>
<label>Read-only</label>
<input
type="text"
value="Read-only value"
readonly
/>
</l-form-field>
<l-form-field>
<label>Disabled</label>
<input
type="text"
value="Disabled value"
disabled
/>
</l-form-field>
<l-form-field>
<label>Invalid</label>
<input
type="email"
value="not-an-email"
aria-invalid="true"
/>
<p class="l-error">Enter a valid email address.</p>
</l-form-field>
</div>Size & radius
Override --height for the control height and --border-radius for the corners.
Password toggle
Add password-toggle on l-input-group — a show/hide button is injected when JavaScript loads (aria-pressed, localized label, Eye/EyeOff icon). Without JavaScript the field stays a plain password input.
Code
<div class="max-w-sm">
<l-form-field>
<label>Password</label>
<l-input-group password-toggle>
<input
type="password"
value="supersecret"
autocomplete="current-password"
/>
</l-input-group>
</l-form-field>
</div>Examples
Icons & units
A replaced <input> can't hold children, so wrap it in l-input-group: the group draws the border and the inner input becomes borderless — no class needed. Children render in DOM order, so an <l-icon> before the input is a leading adornment, a <span> after it is a trailing one.
Code
<div class="grid gap-4 max-w-sm">
<l-form-field>
<label>Search</label>
<l-input-group>
<l-icon name="lucide:search"></l-icon>
<input
type="search"
placeholder="Search"
/>
</l-input-group>
</l-form-field>
<l-form-field>
<label>Height</label>
<l-input-group>
<input
type="number"
placeholder="Placeholder text"
/>
<span>cm</span>
</l-input-group>
</l-form-field>
<l-form-field>
<label>Email</label>
<l-input-group>
<l-icon name="lucide:mail"></l-icon>
<input
type="email"
placeholder="jane@acme.com"
/>
</l-input-group>
</l-form-field>
</div>With a hint
.l-hint adds always-visible helper text, linked to the control via aria-describedby.
We'll never share it.
Code
<l-form-field>
<label>Email</label>
<input
type="email"
placeholder="jane@acme.com"
/>
<p class="l-hint">We'll never share it.</p>
</l-form-field>Accessibility
Criteria
- Input purpose
Set
typeandautocompleteso the field communicates its purpose and benefits from autofillWCAG1.3.5RGAA11.13
Keyboard interactions
API reference
Importing
@import 'luxen-ui/css/input';import 'luxen-ui/input-group';The CSS covers everything except the password toggle; the JS import upgrades l-input-group with its behavior.
Attributes & Properties
typetext | search | number | password | email | url | tel | date | timeAttribute- Native input type.
date/timeget custom picker icons;searchgets a custom clear button. data-sizexs | sm | md | lg | xlAttribute- Control height on the shared
--l-size-control-*scale (defaultmd). Affects only the height, not the label or hint/error. placeholderAttribute- Native placeholder text.
disabledAttribute- Disables the input.
requiredAttribute- Marks the input as required for form submission.
readonlyAttribute- Makes the input read-only.
aria-invalidAttribute- Set to
trueto force the invalid style (otherwise applied via:user-invalid).l-form-fieldmanages this automatically.
CSS classes
.l-inputClass- Base input style, applied to a text-like
<input>(text, search, number, password, email, url, tel, date, time, …). Insidel-form-fieldorl-input-groupa bare text input is auto-styled, so the class is optional there.
CSS custom properties
--heightdefault:var(--l-form-control-height)Custom property- Control height.
--border-radiusdefault:var(--l-form-control-border-radius)Custom property- Control border radius.
--calendar-iconCustom property- Date picker glyph as a
url(). Masked, so color is taken from the control, not the image. --clock-iconCustom property- Time picker glyph as a
url(). --clear-iconCustom property- Search clear glyph as a
url().
Input group
password-togglebooleandefault:falseProperty- Inject a show/hide toggle button after the inner
input[type="password"]. size'xs' | 'sm' | 'md' | 'lg' | 'xl' | undefineddefault:mdProperty- Control size — maps the height to the shared
--l-size-control-*scale ().
.l-input-group-toggleClass- The injected show/hide password button.