better-accessibility
Review and improve focus states, keyboard support, ARIA, forms, screen readers, hit areas, and motion accessibility.
Install
npx skills add https://github.com/jakubkrehel/skills --skill better-accessibilityForms
Labels, autocomplete, error messaging, input types and submit behavior.
Labels
Every control needs a programmatic label: <label for> pointing at the input's id, or a wrapping <label>. A placeholder disappears the moment the user types and usually fails contrast, so it never stands in for a label.
Clicking "Send me updates" toggles the checkbox, with no dead zone between them. Mark required fields with native required plus a visible indicator explained once per form ("* required").
Error messaging
The complete pattern:
aria-invalid="true"on the failing field, removed once fixed.aria-describedbylinks the field to its inline error so screen readers announce it with the field.- Errors render inline beside their fields, with an icon or text. Never a red border alone, which is a color-only cue.
- On submit, focus the first invalid field.
- Accept free text and validate after. Never block typing or filter characters as the user types. Trim values before validating, because autocomplete and text expansion add trailing spaces.
Autocomplete and input types
A valid autocomplete token on fields about the user is a WCAG requirement (1.3.5). Pair it with a descriptive name attribute, a real <form> and no fake inputs, so password managers and 2FA autofill work. The common tokens:
Prefix with a section where relevant: autocomplete="shipping street-address".
Correct type and inputmode pick the right mobile keyboard:
Disable spellcheck on emails, codes and usernames: spellcheck="false".
Submit behavior
- Keep submit enabled until the request starts. While it runs, show a spinner beside the original label: "Save" with a spinner, not a bare spinner. The label is what tells assistive tech which button is busy.
- Mark the pending button
aria-disabled="true"and ignore repeat clicks in the handler. Nativedisabledon the focused button drops focus to<body>. - Announce results. Success goes through a polite live region. On failure, focus the first invalid field, which is itself the announcement. Reserve
role="alert"for form-level errors not tied to a field (screen-readers.md [blocked]). - Warn on unsaved changes before navigation. A re-render or hydration must never reset a field's typed value or move focus out of it.