Input
Text inputs for single-line text entry. Supports all standard HTML input types.
Inputs are width: 100% by default. Do not add af-w-full. Stretch buttons with that utility instead. af-is-autosize is the exception (width: fit-content).
Every input must have an associated <label> — for matching the input id, or wrap the control. A placeholder is not a label. Use the Field pattern for the usual label + control + help/error structure.
Input types
Section titled “Input types”<div class="af-stack">
<div class="af-field">
<label class="af-field__label" for="input-text">Name</label>
<input type="text" id="input-text" class="af-input" placeholder="Ada Lovelace" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-email">Email</label>
<input type="email" id="input-email" class="af-input" placeholder="ada@example.com" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-password">Password</label>
<input type="password" id="input-password" class="af-input" placeholder="••••••••" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-search">Search</label>
<input type="search" id="input-search" class="af-input" placeholder="Find packages" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-tel">Phone</label>
<input type="tel" id="input-tel" class="af-input" placeholder="+61 4 0000 0000" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-url">Website</label>
<input type="url" id="input-url" class="af-input" placeholder="https://example.com" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-number">Quantity</label>
<input type="number" id="input-number" class="af-input" placeholder="12" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-date">Date</label>
<input type="date" id="input-date" class="af-input" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-time">Time</label>
<input type="time" id="input-time" class="af-input" />
</div>
</div>States
Section titled “States”<div class="af-stack">
<div class="af-field">
<label class="af-field__label" for="input-normal">Name</label>
<input type="text" id="input-normal" class="af-input" placeholder="Ada Lovelace" />
</div>
<div class="af-field">
<label class="af-field__label" for="input-error">Email</label>
<input
type="email"
id="input-error"
class="af-input af-is-error"
aria-invalid="true"
aria-describedby="input-error-message"
placeholder="ada@example.com"
/>
<div class="af-field__error" id="input-error-message">Please enter a valid email address</div>
</div>
<div class="af-field">
<label class="af-field__label" for="input-disabled">Name</label>
<input type="text" id="input-disabled" class="af-input" disabled placeholder="Ada Lovelace" />
</div>
</div>Autosize input (experimental)
Section titled “Autosize input (experimental)”Use af-is-autosize to let single-line inputs grow with content:
<div class="af-field">
<label class="af-field__label" for="input-autosize">Tag</label>
<input type="text" id="input-autosize" class="af-input af-is-autosize" placeholder="Type to grow" />
</div>Info: Inputs growing horizontally as you type can cause layout shifts (bad in modern UI/UX). Use autosize only for narrow, controlled cases (like tag inputs or inline search).
Component tokens
Section titled “Component tokens”Form controls use shared control tokens plus input-specific tokens (applies to inputs, selects, and textareas):
--af-control-radius,--af-control-border,--af-control-border-width--af-input-radius(defaults to--af-control-radius)--af-input-min-height,--af-input-border-width(defaults to--af-control-border-width),--af-input-border--af-input-border-hover,--af-input-border-focus--af-input-font-size,--af-input-leading,--af-input-placeholder-color--af-input-padding-x,--af-input-padding-y
<style>
:root {
--af-input-min-height: 3rem;
--af-input-border-focus: var(--af-color-info);
--af-input-placeholder-color: rgba(0, 0, 0, 0.45);
}
</style>
<div class="af-field">
<label class="af-field__label" for="input-custom">Name</label>
<input id="input-custom" class="af-input" placeholder="Ada Lovelace" />
</div>Corner radius
Section titled “Corner radius”Inputs use --af-input-radius, which defaults to --af-control-radius and then --af-radius. Set --af-radius on :root to round fields, cards, and buttons together. Override --af-input-radius only when fields should be tighter or squarer than boxed UI.
<style>
:root {
--af-radius: var(--af-radius-sm);
}
</style>
<div class="af-stack input-radius-sm-demo">
<div class="af-field">
<label class="af-field__label" for="input-radius-email">Email</label>
<input id="input-radius-email" class="af-input" placeholder="ada@example.com" />
</div>
<button type="button" class="af-btn">Continue</button>
</div>Error handling
Section titled “Error handling”Required for accessibility: When showing errors, you must:
- Set
aria-invalid="true"on the input - Link the error message via
aria-describedby(input references error messageid)
<div class="af-field">
<label class="af-field__label" for="input-invalid-email">Email</label>
<input
type="email"
id="input-invalid-email"
class="af-input af-is-error"
aria-invalid="true"
aria-describedby="input-invalid-email-error"
placeholder="ada@example.com"
/>
<div class="af-field__error" id="input-invalid-email-error">Please enter a valid email address</div>
</div>