Input
How the Input works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.
The Input is a native <input> with a <label> tied to it by for and id, and a hint linked with aria-describedby. The browser supplies typing, selection and the right keyboard for the type. What is left is the name, the error state, and contrast for a field drawn with a pale stroke.
Keyboard#
Moves focus into the field, then to its show-password, copy or Verify button where there is one.
Moves focus to the previous focusable element.
Submits the form the field is in. In a search field, runs the search.
In a search field, clears the text, as the browser does.
On the show-password button, shows or hides the password.
Semantics#
<label for>Gives the field its name, and a click on the label focuses the field.
Alwaystype="search" | "password" | "url"Matches the content, so devices show the right keyboard and password managers recognise the field.
Per typerequiredAnnounced as required. The red asterisk is hidden from assistive tech because this says it.
requiredaria-invalid="true"Announced as invalid. The hint says what to fix.
erroraria-describedbyLinks the hint or error, so it is read after the name.
HintautocompletePassword fields use current-password. Other types are off by default; pass a token such as email or name for anything about the person.
Personal dataaria-label="Show password"The button's name says what it will do, and changes to Hide password.
Passwordreadonly / disabledRead Only stays focusable and its value can be copied; Disabled leaves the tab order.
Read Only, DisabledColour contrast#
Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.
Value and label · Default, Hover, Focused, Read Only
The value and label in #2a2a2a, on white, the 4% hover wash and the #f2f2f2 read-only fill. All pass.
WCAG 1.4.3 Contrast (Minimum) ↗Placeholder · Empty
#8f8f8f measures 3.23:1 on white and less on hover. Placeholder text is text, so it fails, and it is no substitute for a label.
WCAG 1.4.3 Contrast (Minimum) ↗WCAG 3.3.2 Labels or Instructions ↗Field boundary · Default, Hover
The 1px #e1e1e1 stroke is 1.31:1 on white: the field is hard to find on a white page. The focused (#070707) and error (#ec0d33) strokes pass.
WCAG 1.4.11 Non-text Contrast ↗Error · Error
The red stroke is backed by the hint's words and aria-invalid. The hint's red is 4.49:1, a hair under 4.5:1.
WCAG 1.4.1 Use of Color ↗WCAG 3.3.1 Error Identification ↗Focus indicator · Focus visible
A 2px ring in #1a6ef8 off a white gap, on keyboard focus only. It measures 4.54:1 on white, so it clears 3:1 on every light surface the library uses.
WCAG 1.4.11 Non-text Contrast ↗WCAG 2.4.13 Focus Appearance ↗Disabled · Disabled
Inactive controls are exempt. The disabled text and glyphs (#cbcbcb) are deliberately faint.
WCAG 1.4.3 Contrast (Minimum) ↗Measured contrast#
Each part against the field's white fill, or the 4% hover wash over it, from the ds.css tokens; text is held to 4.5:1 and the stroke and glyph, as graphics, to 3:1. 8 of 20 pairs fall below their minimum (4.5:1 for text, 3:1 for graphics) and are marked in amber.
Motion#
- The fill and stroke change over 150ms, and are turned off under prefers-reduced-motion.
Checklist#
Every field has a visible label. A placeholder is not a label: it disappears as soon as someone types.
Pass an autocomplete token for anything about the person (name, email, tel, street-address); the component's default is off (WCAG 1.3.5).
The placeholder (#8f8f8f, 3.23:1) is under 4.5:1. Use it only for an example that is also safe to miss, never for instructions.
The resting stroke (#e1e1e1, 1.31:1) is under the 3:1 non-text minimum, so an empty field on white is hard to see. It needs a darker stroke before the code library ships.
The show-password button sets aria-pressed as well as changing its name, so it is announced as Hide password, pressed. Keep one: the changing name.
Validate on blur or submit, not on every keystroke, and move focus to the first invalid field on submit.
The field is 60px tall and the whole box focuses the input, well over the 24px minimum.
