Forms & Accessible Error Handling
📝 Forms & Accessible Error Handling
Label/Input Association Is Load-Bearing
A matched <label for>/id pair isn't a nice-to-have — clicking the label text focuses the input (a larger click target, helping motor disabilities too), and a screen reader announces the label the moment the input receives focus. Without it, an input is announced as just "edit text," with no indication of what it's for.
🚫 The Placeholder-as-Label Anti-Pattern
Placeholder Alone vs a Real Label
Placeholder Only
Disappears the moment typing starts (losing the field's purpose exactly when reviewing it matters most), typically lower contrast by default, and unreliably announced — or not announced at all — by screen readers.
Real <label>
Always visible, always announced, always contrast-compliant text — works correctly for everyone, no exceptions.
If a visually minimal design is genuinely wanted, use a visually-hidden label class — never remove the label element itself.
Fieldset/Legend for Grouped Controls
A Labeled Radio Group
A screen reader announces the <legend> as the user navigates into the group — "preferred contact method" — before hearing each individual option, essential context that a plain nearby visual heading with no programmatic connection would never provide.
❌ Accessible Error Handling
An Invalid Field, Correctly Wired
aria-invalid
Announces the invalid state itself to a screen reader — not just a visual red border sighted users notice.
aria-describedby
Programmatically links the field to its specific error text, so the message is announced whenever the field is reached — not just displayed nearby with no connection.
Error messages should be specific and actionable, not just "invalid input" — Chapter 1's Understandable principle applies directly here. On a failed submission, move focus to the first invalid field (or an error summary), rather than leaving the user unaware anything went wrong — a direct extension of Chapter 4's focus-management theme.
💻 Coding Challenges
Challenge 1: Fix a Placeholder-Only Field
Given <input type="text" placeholder="Full name"> with no label, rewrite it with a proper <label>.
Goal: Practice the single most common form-accessibility fix.
Challenge 2: Group a Checkbox Set
Given three unlabeled checkboxes for "Email me updates," "SMS me updates," and "Push notifications" with a nearby but unconnected visual heading "Notification preferences," wrap them correctly using <fieldset>/<legend>.
Goal: Practice applying fieldset/legend to a realistic checkbox group.
Challenge 3: Wire Up an Accessible Error
A password field fails validation with the message "Password must be at least 8 characters." Write the complete, correctly-associated HTML for the input and its error message.
Goal: Practice combining aria-invalid and aria-describedby correctly in one example.
aria-label Instead of a Visible LabelIt's tempting to add aria-label to satisfy an accessibility checklist or scanner, when a genuinely visible <label> would have been just as easy to add and serves far more people. aria-label only helps screen reader users — it does nothing for users with cognitive disabilities, low vision, or anyone who simply benefits from seeing what a field is for rather than inferring it from context. A visible label serves everyone at once; reserve aria-label for cases where a visible label genuinely isn't appropriate (a well-known icon-only search field, per Chapter 3), not as a default shortcut to make an automated test pass.
🎯 What's Next
With forms covered, the next chapter turns to what's actually visible: Color, Contrast & Visual Design — WCAG contrast ratios, never relying on color alone, and respecting reduced-motion preferences.