Using labels in a nice semantic fashion
It is fairly easy to distinguish a developer’s knowledge level by their usage of label
elements. To see how much they care about accessibility, usability and semantics.
If this is something new to you, I’d recommend that you first read Label – the secret element. What I wanted to touch on here is the semantic value on how you use the label
element together with form elements (e.g. input
elements, textarea
elements).
Ways to use label
The most common is like this:
<label for="user-name">Name</label>
<input id="user-name" type="text">
Another way which has become fairly popular is to wrap the corresponding form element within the label element, e.g:
<label>
Name
<input id="user-name" type="text">
</label>
With this approach you don’t need to specify the for
attribute to know which element should get focus when you click on the text name. That is, for most web browsers but Internet Explorer; there you still have to specify the id
of element you want to connect to the label
.
However, looking at this last approach I’d say that it’s less good from a semantic standpoint. Just looking at the word label, tasting it, it is exactly what it is: a label. Putting any form element within the label takes away the value of the label, and instead becomes some sort of block element (fieldset
or div
), like a container, but with label functionality thrown in for good measure.
In my mind the form element isn’t a part of the label; it has a connection to it. I’m sure some people would like to argue that it is nice for the structure to put the connected form element within its label, but for such relations we have the for
attribute.
My recommendation is: no form elements within labels.
I'm in agreement with you Robert. I also find it easier to style the label and its corresponding element if they are split into separate entities.
I hadn't thought about it before, but I totally agree that it isn't very semantic.
Also, like Phil said, Wrapping the label around the input makes it a lot harder to style the form using CSS.
It's however a shame that there isn't an easier method to link labels and inputs.
Totally agree with you, Robert! I couldn't understand it when I started seeing that around… I feel good knowing that I'm not missing anything.
I only use the last example for checkboxes and radio buttons since it makes it easier to position them.
The <code>for</code> attribute is as always present.
Ya, I agree as well. A good tip!
I was at the Webmasters Jam Session in Dallas, Texas (USA) last week where Derek Featherstone spoke about accessibility and labels. He highlighted a semantic, accessible crossword puzzle created a few years back – not sure if you've seen it already.
The form element is inside the label, though he does use the "for" attribute.
Sad to say I've never done much with the label element. Mostly out of ignorance I'm sure. Great post though Robert. Some good stuff you've got linked together here. Saving this one to snack on a bit later… or over and over again. Del.icio.us
I have to say that I disagree here. The form element is meaningless without the label so I fail to see why encapsulating the form element within the label could be seen as bad.
Perhaps the name "label" is what's at fault. In actual fact the label element defines the form item and what it is the item is trying to capture. The form element really only provides the data format. In that context, it makes perfect sense to make the label element an integral, structural part of the form.
Robert: Just would like to first suggest a correction to your first example: you have user-mane and user-name.
My preference is having the label element separate from the form control for CSS reasons. However, either way, I would use the for/id elements (matching properly of course, :-)) because without the for attribute, when you click on the label text, the option/control is not selected in IE whereas with the for attribute, the option/control is selected when you click on the label text.
Totally agreed. Form controls inside labels don't make sense.
I vote for the "label-outside-formfield". I am used to take JS to improve accessibility of my forms and when you have the for argument, it is easier to handle the elements in DOM. In case of making compact forms (labels convert to a auto-hiding default value), the concept "form field within a label" is a problem.
True, divitis by any other name is still divitis. Nice article Robert, I wasn't aware you could use label in this way. Thanks.
Good to see that so many share my opinion!
Deborah,
Ah, good ol' mr. Featherstone. I guess I need to have a talk with him then! π But I don't think it's necessarily poor accessibility, it's more about semantic meaning and, to me, not exactly using the element as it was intended.
Nick Webb,
Partly, I agree with you; it is good to set up a connection, but usually the <code>for</code> attribute is sufficient for this. But I don't think that a <code>label</code> element is the solution. I'd rather say that we're missing a proper elements for this in the specification.
Jules,
Thanks! Fixed it.
If you want to use implicit labels, but accentuate which part is the label, then wrap the label text in a definition tag (<code><abbr title="definition tag">DFN</abbr></code>), like so:
<code>
<label for="comment">
< dfn>Comment</dfn>
<textarea name="user_comment" id="comment"> </textarea>
</label>
</code>
jbot,
Well, that is a way to use it. But I still think that it shouldn't include the form element within the <code>label</code> element.
I agree with the point on the form field outside the <code>label</code> element. But I think it might good to put the form field inside the <code>label</code> element when it is a check box or radio box. In this way it is easier to click on those little buttons with their label.
Arjan,
That is a nice feature, but it's achieved with using a correct <code>for</code> attribute, not necessarily having the, for example, checkbox within the <code>label</code> element.
I always put the form-element inside the label because I think the extra id-attribute clutters the code.
I don't understand why the for-attribute can't work with the (required) name-attribute of the form-element instead? That way you wouldn't need to mess up your code with unnecessary attributes.
I stopped caring about IE years ago so not really bothered that it doesn't work there.
Andreas,
Well, most of us don't have the luxuary to not support a web browser that has about 90% of the web browser market… π
That's true, and at work neither do I, but on personal projects I don't really care about IE and always encourage IE users to upgrade to a modern browser.
I believe that if more people did that, less people would be using IE…
Andreas,
Absolutely, educating people is the key.
I totally agree, but I must say both methods seem a little weird to me.
The first one bothers me because the label is in fact an element of the form element and it is strange to have two separated things that must be connected, which happens in both ways (by the for attribute in the first, and by inclusion in the second)
I would really like if labels could be written like this:
<input id="user-name" type="text" label="Name">
To me, seems natural that the label is a part of the form element as much as the id or the value, but not otherwise as the second mode suggests. Anyway, among the possible options, I certainly stick with the one you propose.
Guilherme,
That would be a nice way to do it. However, not an alternative in our toolbox: π
Yes, I know. But one can dream, can't one? π
Guilherme,
Always! π
<code>
<label>
Name
<input id="user-name" type="text">
</label>
</code>
Don't do this – it doesn't work well in screen readers, and it doesn't make much semantic sense either. Labels describe forms, they don't contain them.
If you split out the label and the input elements, you can use complicated-looking CSS float techniques to create pseudo-tables. float the labels to the left and the inputs to the right, then each input+label pair can become a table row. It's very lean, it degrades nicely (especially for low-resolution devices) and it's very lightweight.
I love the label element and I find it depressing when people don't use it at all. Especially for checkboxes, that little box is too small of a target for my click – let me click the word instead.
Also, using the label instead of plain text or some other kind of node allows a lot of very fancy CSS hover effects and some very fancy looking form validation feedback.
Guilherme Zuhlke O’Connor, with your suggest, we won't be able to apply styles on the label