devnotes.

Labels, Fieldsets, and Accessibility in Forms

Beyond validation, well-built forms group related fields and clearly label everything so assistive technology can navigate them predictably.

<fieldset> and <legend> group related inputs under a shared heading:

<form>
  <fieldset>
    <legend>Contact Preferences</legend>

    <input type="checkbox" id="email-updates" name="contact" value="email">
    <label for="email-updates">Email me updates</label><br>

    <input type="checkbox" id="sms-updates" name="contact" value="sms">
    <label for="sms-updates">Text me updates</label>
  </fieldset>
</form>

A screen reader announces the <legend> text ("Contact Preferences") before reading each checkbox, giving context that would otherwise be missing.

Two ways to associate labels, both valid:

<!-- Explicit: for + id -->
<label for="phone">Phone</label>
<input type="tel" id="phone" name="phone">

<!-- Implicit: wrapping -->
<label>
  Phone
  <input type="tel" name="phone">
</label>

Both make the label clickable and screen-reader-friendly; the explicit for/id pairing is generally preferred since it works even when CSS separates the label visually from the input.

Practical accessibility checklist for forms:

  • Every input has an associated <label>.
  • Error messages are placed near the field they describe and use aria-describedby when possible.
  • Related fields (like a group of radio buttons) are wrapped in <fieldset>/<legend>.
  • The tab order (the order fields appear in the HTML) matches the visual reading order.