Form Anatomy
Every form has the same parts: labels, inputs, help text, validation, and submission. Get the structure right before styling.
Every form field needs: a label (what is this?), the input (where they type), required indicator (is this optional?), and optionally help text (additional context).
Rule: Every input needs a label. No exceptions.
Top labels are fastest to scan and work best on mobile. Left labels save vertical space but slow scanning. Placeholder-only labels disappear on focus — users forget what field they're filling out.
Accessibility: Never use placeholder as the only label
<input type="email" />
// Label click doesn't focus input
<input type="email" id="email" />
// Click label → focuses input
Labels must be programmatically associated with inputs using for="id". This makes the label clickable (bigger tap target on mobile) and announces correctly to screen readers.
Required: for="id" makes labels clickable and accessible
<fieldset> groups related inputs. <legend> provides the group label. Essential for radio/checkbox groups and address blocks. Screen readers announce the legend with each field.
Structure: fieldset groups related fields semantically