Text input

Single-line inputs of type text, email, number, password, search, tel, and url share one rule block. Theme-aware surface via --kc-input-bg / --kc-input-fg; border tint mixed against currentColor so it tracks the active theme. Validation routes through :user-invalid + [aria-invalid="true"] via the shared controls.invalidControl() mixin.

Live

Across types, with disabled

<div style="display: flex; flex-direction: column; gap: 0.5rem;">
<input type="text" value="Hello" />
<input type="email" placeholder="name@example.com" />
<input type="search" placeholder="Search…" />
<input type="number" value="42" />
<input type="text" value="Can't touch this" disabled />
</div>
@use '@adnap/krysalicss' with (
  $feature-list: ('base-reset', 'base-global', 'element-text-input')
);
Playground

Markup

markup
<input type="text" value="Hello" />
<input type="email" placeholder="name@example.com" />
<input type="search" placeholder="Search…" />
<input type="number" value="42" />
<input type="text" value="Can't touch this" disabled />

When to use

  • Free-form single-line input. Pick the most specific type so mobile keyboards and built-in validation kick in.
  • For multi-line input use Textarea.
  • For one-of-many selection use Select.
  • Pair with Field for a label + help + invalid-glyph wrapper.

Variables

VariableDefaultNotes
$selectorSelector list spanning email, number, password, search, tel, text, urlAlphabetical for deterministic output. Listed individually, not via input:not([type]), because the latter also matches non-text controls.
$padding-y$size-extra-small (0.5rem)Vertical padding.
$padding-x$size-small (0.75rem)Horizontal padding.
$border-radius$global-border-radius (5px)Outer corner radius.
$border-width$global-border-width (1px)Stroke. Mixed at $border-mix against currentColor.
$focus-outline-width$global-focus-outline-width (2px)Focus-visible ring width.
$focus-outline-style$global-focus-outline-style (solid)Focus ring style.
$focus-outline-offset$global-focus-outline-offset (2px)Gap between border and ring.
$disabled-opacity$global-disabled-opacity (0.6)Routed through controls.disabledControl().
$border-mix$global-border-mix (50%)Border tint vs. currentColor. Clears WCAG 1.4.11 (3:1) on shipped themes.

Override example

app.scss
@use '@adnap/krysalicss/element/text-input' with (
  $padding-y: 0.5rem,
  $padding-x: 0.875rem,
  $border-radius: 8px,
);

Tokens consumed

TokenUsed for
--kc-input-bg / --kc-input-fgSurface fill and text colour. Optional: falls back to transparent + currentColor.
--kc-fgFocused border colour and (with --kc-focus-ring) focus-ring fallback.
--kc-focus-ringPainted on :focus-visible. Falls back to --kc-fg then currentColor.
--kc-danger-bgBorder tint when the control matches :user-invalid or [aria-invalid="true"].

Accessibility

  • Anchored on native <input>: every assistive-tech contract is the browser's. Use the most specific type so mobile keyboards and built-in validation engage.
  • Always pair with a <label> (visible or aria-labelledby) — placeholders alone fail WCAG 3.3.2.
  • Focus ring uses --kc-focus-ring with a fallback chain into --kc-fg / currentColor; the focused border also swaps to --kc-fg for redundant non-text contrast (WCAG 2.4.11 + 1.4.11).
  • Invalid state routes through :user-invalid + [aria-invalid="true"], so untouched required fields don't flag on first paint.
  • The padded box clears the WCAG 2.5.5 (44 × 44 px) touch-target floor at the default $size-extra-small padding.

See also

  • Textarea — multi-line text input with the same border / focus chrome.
  • Select — dropdown one-of-many selection.
  • Forms overview — full form-control roster.
  • Field wrapper — pairs every form control with label + help text.