# Review form includes required and optional fields clearly marked

- **Pattern:** `ab-001203` (`ecommerce-reviews.review-collection.form-fields-labeled`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001203
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001203)

## Why it matters

WCAG 2.2 SC 1.3.1 (Info and Relationships) and SC 3.3.2 (Labels or Instructions) require that every form input have a programmatically associated label and that required fields be identified. A review form where labels exist only as placeholder text fails both criteria: placeholders vanish on focus, and screen readers cannot associate floating-label text with the input's purpose. A form that doesn't distinguish required from optional fields produces higher abandonment rates — users guess wrong, get validation errors, and leave. This is particularly acute for star rating inputs and photo upload fields that have no obvious placeholder.

## Severity rationale

Medium because inaccessible labels break screen reader navigation and increase form abandonment without creating a data or security exposure.

## Remediation

Use explicit `<label htmlFor>` elements tied to each input's `id`, and mark every field's required or optional status in the review form component.

```tsx
<form>
  <div>
    <label htmlFor="rating">
      Rating <span aria-label="required" className="text-red-500">*</span>
    </label>
    <StarInput id="rating" aria-required="true" />
  </div>

  <div>
    <label htmlFor="review-text">
      Your Review <span aria-label="required" className="text-red-500">*</span>
    </label>
    <textarea id="review-text" required minLength={10} />
  </div>

  <div>
    <label htmlFor="photos">
      Photos <span className="text-muted">(optional)</span>
    </label>
    <input id="photos" type="file" accept="image/*" multiple />
  </div>
</form>
```

Do not rely on placeholder text to convey label meaning — it disappears on focus and has no ARIA role.

## Detection

- **ID:** `form-fields-labeled`
- **Severity:** `medium`
- **What to look for:** Count every form field in the review submission form. For each field, classify whether it has: (1) a visible `<label>` element, (2) a required/optional indicator (asterisk, "required" text, or aria-required), (3) helper text or placeholder. Report: X of Y fields have all 3 attributes.
- **Pass criteria:** At least 80% of form fields have visible `<label>` elements with `htmlFor` matching the input's `id`. All required fields are marked with an asterisk (*), "required" text, or `aria-required="true"`. At least 1 optional field is explicitly labeled as "(optional)".
- **Fail criteria:** Fewer than 80% of form fields have visible labels, or required/optional status is unclear on any field, or labels use only placeholder text that disappears on focus.
- **Skip (N/A) when:** No review submission form exists (submission-form-exists already failed or skipped).
- **Detail on fail:** `"3 of 5 form fields have visible labels (60%). Rating and photos fields use placeholder-only. 0 fields marked as required or optional."` or `"All fields have labels but no required/optional indicators — user cannot distinguish mandatory from optional."`
- **Remediation:** Use explicit labels and required indicators in the review form component:

  ```tsx
  <form>
    <div>
      <label htmlFor="rating">Rating <span aria-label="required">*</span></label>
      <StarInput id="rating" required />
    </div>

    <div>
      <label htmlFor="text">Your Review <span aria-label="required">*</span></label>
      <textarea id="text" required />
    </div>

    <div>
      <label htmlFor="photos">Photos <span>(optional)</span></label>
      <input id="photos" type="file" accept="image/*" multiple />
    </div>
  </form>
  ```

---

## External references

- wcag 1.3.1
- wcag 3.3.2

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-001203
