HTML forms
The HTML label, explained.
A <label> is the visible name of a form field. Connected properly, it tells screen readers what the field is, and makes the text itself clickable. Here are the two ways to connect one, the common mistakes, and how to style labels.
Updated 7 November 2026
Connect a label with for and id
<label for="email">Email</label>
<input id="email" type="email" name="email" />- for on the label matches the id of the field. The id must be unique on the page.
- Clicking the label focuses the field, or ticks it for a checkbox or radio button. That gives everyone a bigger target, especially on phones.
- Screen readers announce the label when the field is focused: “Email, edit text”.
- for points at id, not name.
nameis the key the value is sent under;idis what the label connects to. They are often the same word, but they do different jobs.
Or wrap the field in the label
Putting the field inside the label connects them without for and id. This is common for checkboxes and radio buttons, where the text sits right next to the box.
<label>
Email
<input type="email" name="email" />
</label>Both ways work in current browsers and screen readers. Adding for and id even to a wrapped label is the most robust choice, because some older assistive software only understood the explicit link.
A placeholder is not a label
Placeholder text disappears as soon as someone starts typing, so they lose the field’s name exactly when they need it, and it is usually pale grey text that is hard to read. Use a visible label for the name, and keep placeholders for an example value, if anything.
For extra instructions, put them in their own element and connect it with aria-describedby. Screen readers read it after the label:
<label for="password">Password</label>
<input id="password" type="password" name="password" aria-describedby="password-hint" />
<p id="password-hint">At least 12 characters.</p>Rules worth knowing
- One field per label. A label names one field. A field can have more than one label, but that is rarely useful.
- Labels work on input (except hidden inputs), select, textarea, button, meter, output and progress.
- Keep links and buttons out of labels where you can, because clicking the label then has two possible meanings. The common exception, an “I agree to the privacy policy” checkbox, works fine.
- In React, the attribute is written
htmlFor, becauseforis a reserved word in JavaScript.
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" />Style labels
Labels are inline by default. Most forms put them on their own line above the field, which is the easiest layout to scan and works at every screen width:
label {
display: block;
margin: 16px 0 6px;
font-weight: 600;
}
label .optional { font-weight: 400; color: #6b6a80; }Say whether a field is optional or required in the label text itself. An asterisk or colour alone is easy to miss.
A labelled form that sends
This contact form posts to Heartdove, which saves every message, emails you an alert and tracks it until it is delivered or bounces. Labels are for people on your page and are not sent; each field arrives under a readable version of its name, so company shows up as “Company” in your inbox and the alert.
<form action="https://submit.heartdove.com/v1/submit" method="POST">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<label for="name">Name</label>
<input id="name" type="text" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" type="email" name="email" autocomplete="email" required />
<label for="company">Company <span class="optional">(optional)</span></label>
<input id="company" type="text" name="company" autocomplete="organization" />
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<input type="checkbox" name="botcheck" tabindex="-1" autocomplete="off" style="display:none" />
<button type="submit">Send message</button>
</form>Replace YOUR_ACCESS_KEY with your key from a free Heartdove form, or let the contact form generator write the labels for you.
Questions
What does the for attribute do on a label?
It connects the label to the field whose id matches. Clicking the label then focuses the field, and screen readers announce the label for it.
Should I use for, or wrap the input in the label?
Either works. Using for and id is the most robust, and you can combine both: wrap the field and still add for and id.
Can I use a placeholder instead of a label?
No. A placeholder disappears when someone types and is often hard to read. Use a visible label, and a placeholder only for an example value.
What is the difference between a label and aria-label?
A label element is visible text connected to the field. aria-label gives a name only assistive technology can read. Prefer a visible label, or a visually hidden one, where you can.
Why is it htmlFor in React?
for is a reserved word in JavaScript, so React uses htmlFor. It produces the same for attribute in the HTML.
Never lose another enquiry.
Connect your first form in a few minutes. Your existing design stays exactly as it is.