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-describedbywhen 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.