Input — accessibility
Keyboard
- Native
<input>: Tab moves focus in and out, typing edits, Enter submits the enclosing form.disabledremoves it from the tab order;readOnlydoes NOT — a read-only field stays focusable so the value can be selected and copied from the keyboard. - No shortcut chip on the plain input; a shortcut belongs to Input with icon and kbd.
- Inside
.acrm-rangethe two inputs are two tab stops in reading order (from, then to).
ARIA
- No role needed; the element is a native text input.
- Accessible name:
<Field>renders the label as a sibling<label>withouthtmlFor, so the name is not linked automatically — passaria-label, oridon the input andaria-labelledby/ wrap the control in the label yourself. - Error: put
aria-invalid="true"on the input together with.is-error; the class only draws the frame. Link the message witharia-describedbypointing at the.acrm-field-errorelement when the screen renders one. type="email"/type="url"/type="number"expose the matching virtual keyboard and browser validation.
Focus
- The foundation ring in
ds.css(:where(button, a[href], [role=…], [tabindex])) does not cover inputs;.acrm-input:focusdraws its own:outline: none,border-color: var(--accent), 3px ringcolor-mix(in srgb, var(--accent) 16%, transparent). - The ring shows on mouse focus too (
:focus, not:focus-visible) — intended, the caret position matters for pointer users as well. - Error keeps the same geometry with
--critical; a focused error field shows the accent ring (focus rule wins by order).
Contrast
Computed from packages/ui/src/tokens/tokens.css (WCAG 2.x relative luminance):
- Value
--fg#18191b on--surface-100#ffffff = 17.59:1 (light); #eceded on--surface-50#232529 = 13.09:1 (dark). - Placeholder
--fg-muted#98999c on white = 2.85:1 (light); #717479 on #232529 = 3.27:1 (dark) — below AA 4.5:1 for text. - Disabled value
--fg-mutedon--surface-75#fbfbfb = 2.75:1 (light); #717479 on #161719 = 3.82:1 (dark). - Resting border
--border-strong#dcdbdd on white = 1.38:1 (light); #3a3c42 on #1b1c1f = 1.55:1 (dark) — hairline, below the 3:1 non-text minimum. - Focus border
--accent#0072f5 on white = 4.44:1 (light); on #1b1c1f = 3.83:1 (dark) — passes 3:1. - Error border
--critical#e5484d on white = 3.91:1 (light); on #1b1c1f = 4.35:1 (dark) — passes 3:1.
Read-only vs disabled
- Read-only = the value is real and relevant, only not editable here: focusable, announced by screen readers with its value and "read only", selectable, full-contrast text (
--fgon--surface-75, 17:1 light / 15:1 dark). - Disabled = the control does not apply right now: out of the tab order, muted text (below AA, by design). Never use disabled for a value the user needs to read or copy.
Known limits
- Placeholder and disabled text sit below AA; the placeholder is a hint only, the real label and format live in
<Field>. - The resting hairline is far below 3:1; the field is found by its label and the focus ring, not by its border.
<Field>does not link label and control — the accessible name must be added by the screen..is-erroris visual only;aria-invalidis not set by the component.
Source: docs/text-field/input.a11y.md · GitLab