agentsclimarketplace

Form a11y

Skill xrnavigation/web-a11y-plugin/skills/form-a11y

Web accessibility agent skills — 23 cite-backed skills covering APG widget patterns, audit tooling, ARIA guidance, cognitive accessibility, and more. Works with Claude Code, Codex CLI, and Gemini CLI.

Install
npx -y skills add xrnavigation/web-a11y-plugin --skill form-a11y

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Guides comprehensive form accessibility beyond basic labels — error messaging and association, validation patterns, field grouping, accessible authentication (WCAG 2.2), redundant entry prevention, and autocomplete attributes. Auto-invokes when creating forms, validation logic, authentication flows, or multi-step form wizards.

SKILL.md

13.5 KB, as published. Nobody here has run it

Form Accessibility

"The best error message is the one that never shows up." — Thomas Fuchs

Forms are the primary way users provide information on the web. Getting form accessibility wrong locks people out of purchases, registrations, healthcare portals, and government services. This skill covers everything beyond basic <label> + <input> pairing.


1. Error Association

Use aria-describedby + aria-invalid to connect error messages to fields. This is the proven, cross-browser pattern.

<label for="email">Email</label>
<input id="email" type="email"
       aria-describedby="email-error"
       aria-invalid="true">
<span id="email-error">Enter a valid email address, e.g. [email protected]</span>

Rules

  • Set aria-invalid="true" when a field has an error. Remove the attribute entirely (not "false") when valid.
  • Never set aria-invalid before the user interacts. Do not mark required fields invalid on page load.
  • Use aria-describedby to point the input to the error message element's id. Screen readers announce the description when the field receives focus.
  • Multiple descriptions: space-separate IDs to include both a hint and an error:
<input id="phone" type="tel"
       aria-describedby="phone-hint phone-error"
       aria-invalid="true">
<span id="phone-hint">Format: (555) 123-4567</span>
<span id="phone-error">Phone number is required.</span>
  • Do NOT use aria-live on individual field errors. Roselli's testing across seven SR/browser combinations found that aria-live="assertive" on field errors clips the next field name announcement. Chromium/JAWS already treats aria-describedby as an assertive live region, doubling announcements if you also add aria-live. (Roselli, 2023)
  • Do NOT use aria-errormessage in production yet. Support is insufficient as of 2024-2025 — TalkBack has no support, iOS VoiceOver/Safari only partial. Continue using aria-describedby. (Cerovac, 2024)

Limitation

Changes to aria-describedby content while the input is focused will not trigger re-announcement — the user must re-focus the field. (Roselli, 2022)


2. Validation Patterns

Timing

  • Validate on blur, not on every keystroke. The input event fires errors before the user finishes typing — this is disruptive.
  • Refinement: only trigger blur validation if the field value actually changed. This prevents false errors from accidental focus (scrolling, tabbing past).
  • Always validate on submit. Client-side validation can be bypassed; always validate server-side as well.

(TetraLogical, 2024; Smashing Magazine, 2023)

Inline Errors

  • Display error messages near their associated field.
  • Use distinctive styling — not color alone (WCAG 1.4.1). Add an icon, text prefix ("Error:"), or border change alongside color.
  • Associate each error to its field via aria-describedby.

Error Summary

For longer forms, display a summary of all errors above the form (or before the submit button):

  • Include links to each invalid field.
  • Set focus to the summary container after submission.
  • Use aria-live="assertive" on the summary container — not on individual field errors.

For short forms (2-3 fields), focusing the first invalid field with HTMLElement.focus() is sufficient — the screen reader announces the error via aria-describedby.

Recommended: Combined Approach

Use both an error summary and inline errors. The summary provides orientation ("3 errors found"); inline errors provide context at each field. (WebAIM)


3. Field Grouping (fieldset/legend)

Use <fieldset> and <legend> to group related controls. The <legend> acts as the group label — screen readers announce it when a user enters the fieldset.

When to Use

  • Radio button groups — the legend provides the group question
  • Checkbox groups — when checkboxes share a common category
  • Address blocks — shipping vs. billing address sections
  • Related field sets — e.g., "Emergency Contact" fields
<fieldset>
  <legend>Shipping Address</legend>
  <label for="street">Street</label>
  <input id="street" type="text" autocomplete="shipping street-address">
  <!-- more fields -->
</fieldset>

When NOT to Use

  • Do not wrap the entire form in a single fieldset — it adds noise without value.
  • A single input with its own <label> does not need a fieldset.
  • Use fieldset only when fields share a relationship that needs a group label.

4. Required Fields

Visual Indicators

  • Use text "(required)" near the label, not asterisks alone.
  • If using asterisks, include a legend at the top of the form: "Fields marked with * are required."
  • Never rely on color alone (WCAG 1.4.1).
<label for="name">Full Name <span aria-hidden="true">*</span>
  <span class="sr-only">(required)</span>
</label>
<input id="name" type="text" required>

required vs. aria-required="true"

AttributeSR announces "required"Browser-native validationPrevents empty submission
requiredYesYesYes
aria-required="true"YesNoNo

Use required when browser-native validation is acceptable. Use aria-required="true" when you need custom validation UX and want to suppress browser tooltips (add novalidate to the <form>).


5. Accessible Authentication (WCAG 2.2)

SC 3.3.8 — Level AA

A cognitive function test (remembering a password, solving a puzzle, transcribing a code) must NOT be required for authentication unless:

  1. Alternative — another method exists that doesn't require the test
  2. Mechanism — assistance is available (password manager, paste)
  3. Object Recognition — the test uses object recognition (AA only)
  4. Personal Content — the test uses content the user provided (AA only)

SC 3.3.9 — Level AAA

Same as 3.3.8, but only the Alternative and Mechanism exceptions remain.

What Complies

  • Username/password with proper autocomplete attributes (username, current-password, new-password)
  • Paste is not blocked on authentication fields
  • WebAuthn / passkeys (fingerprint, face, PIN)
  • Third-party OAuth (Sign in with Google, etc.)
  • Email-link / magic link authentication
  • Multi-factor with hardware tokens, QR codes, or device notifications

What Fails

  • Blocking paste on password or verification code fields
  • Requiring manual transcription of verification codes without copy/paste
  • CAPTCHAs or puzzles with no alternative
  • Requiring memorization without allowing password managers

Implementation Checklist

<!-- Login form — compliant -->
<form>
  <label for="user">Username</label>
  <input id="user" type="text" autocomplete="username">

  <label for="pass">Password</label>
  <input id="pass" type="password" autocomplete="current-password">
  <!-- Do NOT add onpaste="return false" -->

  <button type="submit">Sign In</button>
</form>

(W3C Understanding SC 3.3.8)


6. Redundant Entry (WCAG 2.2)

SC 3.3.7 — Level A

Information previously entered by the user that is required again in the same process must be either auto-populated or available for the user to select.

Exceptions: re-entry is essential, required for security (password confirmation), or the information is no longer valid.

Implementation Techniques

  • "Billing address same as shipping" checkbox
  • Pre-populate fields from earlier steps (allow edits)
  • Dropdowns populated from previous input
  • Retain field values after validation errors — never clear the form on failed submission
  • Pre-fill search terms on results pages

(W3C Understanding SC 3.3.7)


7. Autocomplete Attributes

The autocomplete attribute enables browsers and password managers to auto-fill fields. Required for WCAG 1.3.5 (Identify Input Purpose) and supports accessible authentication (3.3.8/3.3.9).

Quick Reference

PurposeValues
Identityname, given-name, family-name, nickname, username, organization
Authenticationcurrent-password, new-password, one-time-code
Addressstreet-address, address-line1, address-line2, address-level2 (city), address-level1 (state), country, postal-code
Paymentcc-name, cc-number, cc-exp, cc-exp-month, cc-exp-year, cc-csc
Contacttel, email, url
Personalbday, sex, language, photo

Modifiers

  • Scope: section-{name} groups related fields (e.g., section-emergency-contact)
  • Purpose: shipping, billing prefix address/contact fields
  • Contact type: home, work, mobile prefix tel/email fields
  • WebAuthn: webauthn for passkey/credential fields
<input autocomplete="shipping address-line1" name="ship-street">
<input autocomplete="billing cc-number" name="card">
<input autocomplete="section-emergency-contact tel" name="emergency-phone">

For the complete list of all autocomplete values, see: ${CLAUDE_SKILL_DIR}/references/autocomplete-values.md


8. Common Mistakes

These are real patterns from accessibility audits. Each is cited.

  1. Blocking paste on password fields — prevents password manager use, fails WCAG 3.3.8. (W3C)
  2. Validating on every keystroke — fires errors before the user finishes typing. Validate on blur. (TetraLogical)
  3. aria-live on individual field errors — clips next field announcement in multiple SR/browser combos. Use aria-live only on error summaries. (Roselli)
  4. aria-invalid before user interaction — do not mark required fields invalid on page load. (Deque)
  5. Color alone for error indication — red borders without icons or text fails WCAG 1.4.1. (Smashing Magazine)
  6. Vague error messages — "Invalid input" is unhelpful. Provide specific guidance: "Enter a date in MM/DD/YYYY format." (WebAIM)
  7. Clearing form on validation failure — destroys user input, fails the spirit of SC 3.3.7. (W3C)
  8. Missing autocomplete on login fields — without autocomplete="username" and autocomplete="current-password", password managers can't autofill, risking WCAG 3.3.8 failure. (W3C)
  9. aria-label instead of visible <label> — not translated by many localization tools, doesn't expand click target. Use <label for="..."> first. (Roselli)
  10. Using aria-errormessage in production — insufficient SR support as of 2024-2025. Use aria-describedby. (Cerovac)
  11. Disabled form controls — not focusable, not announced by some screen readers, no explanation of why disabled. Prefer keeping controls enabled and validating on submission. (Roselli)
  12. Wrapping entire field content in <label> — confuses screen readers about actual label text and creates click-conflict with interactive elements inside the label. (Smashing Magazine)

For detailed patterns and anti-patterns, see: ${CLAUDE_SKILL_DIR}/references/common-mistakes.md


9. Cross-References

  • live-regions — for aria-live usage on error summaries and dynamic content announcements
  • cognitive-a11y — for cognitive accessibility considerations (clear language, error recovery, timeouts)
  • aria-decision-framework — for when to use ARIA vs. native HTML elements

For detailed reference material:

  • ${CLAUDE_SKILL_DIR}/references/error-association-patterns.md — complete error association patterns with SR test results
  • ${CLAUDE_SKILL_DIR}/references/autocomplete-values.md — full autocomplete attribute value list
  • ${CLAUDE_SKILL_DIR}/references/common-mistakes.md — anti-patterns with citations
  • ${CLAUDE_SKILL_DIR}/references/sources.yaml — provenance for all cited sources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.