How do you correctly label an input? Why isn't a placeholder a label, and what's wrong with a bare aria-label?
Programmatic label association and the common placeholder-as-label mistake.
Every form control needs a programmatically associated label so its accessible name is announced on focus and its hit target includes the label text. The primary tool is <label>: either wrap the control (<label>Email <input></label>) or, better for styling, use for/id (<label for="email">…</label><input id="email">). A correctly associated label also lets sighted users click the label to focus the control — a usability win for everyone. A PLACEHOLDER is not a label: it disappears the moment the user types (so they lose the field's name mid-entry), it's typically low-contrast (a contrast failure), and support for exposing it as a name is inconsistent — never use placeholder as the only label. aria-label and aria-labelledby can supply a name when a visible label genuinely isn't possible (a search field with only an icon), but they have a cost: aria-label has NO visible text, so voice-control users can't say the label to target it, and sighted users get no caption — prefer a real visible <label> and reserve ARIA labelling for icon-only or space-constrained cases. Group related controls (radio sets, a set of checkboxes) in a <fieldset> with a <legend> so the group's purpose is announced. Required, format hints, and errors are conveyed with required/aria-required and aria-describedby, not baked into the placeholder.
Building any form; killing placeholder-as-label and choosing label vs aria-label.
<!-- Best: visible label associated via for/id -->
<label for="email">Email</label>
<input id="email" type="email" required>
<!-- Also valid: wrapping label -->
<label>Email <input type="email"></label>
<!-- WRONG: placeholder is not a label (vanishes on typing, low contrast) -->
<input placeholder="Email">
<!-- Grouped controls need a fieldset + legend -->
<fieldset>
<legend>Notify me by</legend>
<label><input type="checkbox" name="n" value="email"> Email</label>
<label><input type="checkbox" name="n" value="sms"> SMS</label>
</fieldset>