<label for=“name”>Full Name:</label>
<input id=“firstname” name=“firstname” class=“text” type=“text” />
The “for” attribute of the label should (must) match the id of the input, so the above code has the label not linked to the input.
If you’re going for multiple inputs for one label, one way I’ve done is this way:
<label for=“birthdate”>Date of birth (dd/mm/yyyy): </label>
<input type=“text” id=“birthdate” name=“bday” title=“Enter two-digit day” maxlength=“2”>
<input type=“text” name=“bmonth” title=“Enter two digit month” maxlength=“2”>
<input type=“text” name=“byear” title=“Enter four digit year” maxlength=“4”>
http://juicystudio.com/article/invisible-form-prompts.php
old link but the technique still seems to work
Maxlength is there to reinforce the instructions, which is helpful.
Another way I’ve done it:
(inside the form's main fieldset...)
<div>
<normal label>Label: </label>
<normal input...>
</div>
<fieldset class="access">
<legend>Date of birth</legend>
<p>Date of birth: </p>
<label [b]for="day"[/b]>Day: </label>
<input type="text" [b]id="day"[/b] name="bday" maxlength="2">
<label [b]for="month"[/b]>Month: </label>
<input type="text" [b]id="month"[/b] name="bday" maxlength="2">
<label [b]for="year"[/b]>Year: </label>
<input type="text" [b]id="year"[/b] name="bday" maxlength="4">
</fieldset>
next div with label-input pair...
fieldset.access has the same CSS code as the divs, so it does the same job
fieldset.access legend is moved off-screen, but heard by screen readers who have a Forms Mode.
fieldset.access p is styled like most labels, and is for the sighted users, and as a non-form control it is not read out by any screen readers who have a Forms Mode.
fieldset.access labels are either display: none or pulled offscreen.
Display: none on the Big 2 Windows screen readers (JAWS and Window-EYes) seem to be read out despite their display: none status, for some special reason. Pulling the labels offscreen is a nicer idea, but
Safari and Chrome have some display bug where the abso-po’d labels cause the inline-block inputs to start new lines. For this reason I’ve sometimes display: none’d the labels.
Another way I’ve done it:
<label for=“postcode”>Postcode: </label>
<input type=“text” id=“postcode” name=“postcode1” title=“first 4 digits of postal code” maxlength=“4”>
<label for=“postcode2” class=“access”>Postcode letters: </label>
<input type=“text” id=“postcode2” name=“postcode2” maxlength=“2”>
label.access {
position: absolute;
left: -999em;
}
Again, this makes it look like this in most browsers:
Postcode: 3362 AB
But in Safari and Chrome it’s
Postcode: 3362
AB
So for this reason I’ve been forced again to use display: none instead, relying on the Big 2 still reading them out.
The problem with this though is that there are other readers: NVDA for Windows is free, Orca for Gnome desktops on Linux/OpenSolaris is free and does not have a virtual buffer (I can’t figure out yet if there’s a Forms Mode as I still have trouble working it), VoiceOver comes on all OSX Macs.