53

Does the label tag work with radio buttons? If so, how do you use it? I have a form that displays like this:

First Name: (text field)
Hair Color: (color drop-down)
Description: (text area)
Salutation: (radio buttons for Mr., Mrs., Miss)

I'd like to use the label tag for each label in the left column to define its connection to the appropriate control in the right column. But If I use a radio button, the spec seems to indicate that suddenly the actual "Salutation" label for the form control no longer belongs in the label tag, but rather the options "Mr., Mrs., etc." go in the label tag.

I've always been a fan of accessibility and the semantic web, but this design doesn't make sense to me. The label tag explicitly declares labels. The option tag selection options. How do you declare a label on the actual label for a set of radio buttons?

UPDATE: Here is an example with code:

<tr><th><label for"sc">Status:</label></th>
    <td>&#160;</td>
    <td><select name="statusCode" id="sc">
            <option value="ON_TIME">On Time</option>
            <option value="LATE">Late</option>
        </select></td></tr>

This works great. But unlike other form controls, radio buttons have a separate field for each value:

<tr><th align="right"><label for="???">Activity:</label></th>
    <td>&#160;</td>
    <td align="left"><input type="radio" name="es" value="" id="es0" /> Active &#160;
        <input type="radio" name="es" value="ON_TIME" checked="checked" id="es1" /> Completed on Time &#160;
        <input type="radio" name="es" value="LATE" id="es2" /> Completed Late &#160;
        <input type="radio" name="es" value="CANCELED" id="es3" /> Canceled</td>
</tr>

What to do?

GlenPeterson
  • 4,866
  • 5
  • 41
  • 49
  • 2
    Related answer: http://stackoverflow.com/questions/13080416/labels-checkboxes-and-radio-buttons/13089674#13089674 – Ryan B Nov 09 '12 at 13:56

7 Answers7

62

Does the label tag work with radio buttons?

Yes

If so, how do you use it?

Same way as for any other form control.

You either give it a for attribute that matches the id of the control, or you put the control inside the label element.

I'd like to use the label tag for each label in the left column

A label is for a control, not a set of controls.

If you want to caption a set of controls, use a <fieldset> with a <legend> (and give a <label> to each control in the set).

<fieldset>
  <legend> Salutation </legend>
  <label> <input type="radio" name="salutation" value="Mr."> Mr. </label>
  <label> <input type="radio" name="salutation" value="Mrs."> Mrs. </label>
  <!-- etc -->
</fieldset>
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    Fieldset changes the display on some browsers, no? Also the "legend" and radio buttons are in different table cells in my case. – GlenPeterson Nov 07 '12 at 16:44
  • 1
    Also, a group of radio buttons with the same name attribute are effectively one control. Each ` – GlenPeterson Nov 07 '12 at 17:37
  • 3
    @GlenPeterson: “a group of radio buttons with the same name attribute are effectively one control” — nope, it’s not. They’re linked, sure, but each button is a control. A ` – Paul D. Waite Nov 07 '12 at 23:16
  • I updated Quentin's answer. While ` – Ryan B Nov 09 '12 at 13:53
  • 2
    https://stackoverflow.com/a/4213253/470749 was a helpful reminder for me about removing `for`. – Ryan Apr 03 '18 at 19:09
27

Ah yes. Here’s how it works.

<label> labels individual fields, hence each <input type="radio"> gets its own <label>.

To label a group of fields (e.g. several radio buttons that share the same name), you use a <fieldset> tag with a <legend> element.

<fieldset>
    <legend>Salutation</legend>

    <label for="salutation_mr">Mr <input id="salutation_mr" name="salutation" type="radio" value="mr"><label>

    <label for="salutation_mrs">Mrs <input id="salutation_mrs" name="salutation" type="radio" value="mrs"><label>

    <label for="salutation_miss">Miss <input id="salutation_miss" name="salutation" type="radio" value="miss"><label>

    <label for="salutation_ms">Ms <input id="salutation_miss" name="salutation" type="radio" value="ms"><label>
</fieldset>
Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
  • +1 for answering the specific question and for "harder to style consistently across browsers" even though Quentin might have stolen some of your thunder. The issue with this approach is that I don't think it will work across table cells, especially if the table contains other form elements that are not part of the options for this particular set of radio buttons. – GlenPeterson Nov 07 '12 at 17:51
  • 2
    @GlenPeterson: indeed. If you want your labels in one cell and your form fields in another, the HTML above doesn’t work. Arguably, that’s a reason to not use tables to lay out forms. – Paul D. Waite Nov 07 '12 at 23:13
  • Can you link to a way you would recommend to lay out forms for cross browser compatibility on a variety of screen sizes? Right now we have the field name in the left column, field in the middle, and help text (when appropriate) on the right. – GlenPeterson Nov 08 '12 at 21:27
  • @GlenPeterson: nothing springs to mind for a recommended way to lay out forms. It depends on the form, and what you’re trying to achieve. One thing I personally like is field labels above the field, as then when you select the field on an iPhone you can still see the label after the browser’s zoomed in on the field. – Paul D. Waite Nov 08 '12 at 22:02
  • You should be able to omit the `for` and `id` attributes here since you're wrapping the inputs in `label` – Adam Fraser Nov 07 '17 at 15:36
  • 1
    @AdamFraser: true, you should, although I believe in the past some screen readers didn’t support that very well. One would hope things have improved, but I haven’t tried it recently. – Paul D. Waite Nov 07 '17 at 18:22
  • Seven years later and it is disappointing that the fieldset method is still not practical because fieldset does not play well with flexbox. div role="radiogroup" makes the most sense to me. – Louise Eggleton Aug 12 '19 at 21:34
9

You can use the aria-role="radiogroup" to associate the controls without using a <fieldset>. This is one of the techniques suggested by WCAG 2.0.

<div role="radiogroup" aria-labelledby="profession_label" aria-describedby="profession_help">
  <p id="profession_label">What is your profession?</p>
  <p id="profession_help">If dual-classed, selected your highest leveled class</p>
  <label><input name="profession" type="radio" value="fighter"> Fighter</label>
  <label><input name="profession" type="radio" value="mage"> Mage</label>
  <label><input name="profession" type="radio" value="cleric"> Cleric</label>
  <label><input name="profession" type="radio" value="theif"> Thief</label>
</div>

However, I noticed that using this technique the WebAim Wave tool to give a warning about a missing <fieldset>, so I'm not sure what AT support for this is like.

Scribblemacher
  • 1,518
  • 1
  • 16
  • 31
2

You can't declare a label for a set of buttons, but for each button. In this case, the labels are "Mr.", "Mrs." and "Miss", not "Salutation".

UPDATE
Maybe you should just use another tag for this "label" of yours - since it's not really a label.

<tr>
    <th align="right" scope="row"><span class="label">Activity:</span></th>
    <td>&#160;</td>
    <td align="left"><label><input type="radio" name="es" value="" id="es0" /> Active &#160;</label>
    [... and so on]
</tr>
Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Cesar Castro
  • 1,892
  • 1
  • 13
  • 19
2

my 2 cents to the topic, or rather a side node (it does not use implicit association to be able to be placed anywhere, but linking): grouping is done by the name attribute, and linking by the id attribute:

<ol>
    <li>
        <input type="radio" name="faqList" id="faqListItem1" checked />
        <div>
            <label for="faqListItem1">i 1</label>
        </div>
    </li>
    <li>
        <input type="radio" name="faqList" id="faqListItem2" />
        <div>
            <label for="faqListItem2">i 2</label>
        </div>
    </li>
    <li>
        <input type="radio" name="faqList" id="faqListItem3" />
        <div>
            <label for="faqListItem3">i 3</label>
        </div>
    </li>
</ol>
BananaAcid
  • 3,221
  • 35
  • 38
  • This is the approach that I've taken in the past; whether it is considered a best practice, idk, but it is consistent with how radio buttons are grouped so seems very natural to me. Unfortunately, the defs for label have the label's for attribute associated with an id, not name. So, this approach generates warnings. – Jacob Lee Apr 21 '20 at 16:21
1

To answer your question: no, you can't connect Salutation to one of the radio buttons. It wouldn't make sense that if you'd click on Salutation, one of the options would be selected. Instead, you can give Mr, Mrs and Miss their own labels, so if someone clicks on one of those words, the corresponding radio button will be selected.

<input id="salutation_mr" type="radio" value="mr" name="salutation">
<label for="salutation_mr">Mr.</label>
<input id="salutation_mrs" type="radio" value="mrs" name="salutation">
<label for="salutation_mrs">Mrs.</label>
<input id="salutation_miss" type="radio" value="miss" name="salutation">
<label for="salutation_miss">Miss</label>

I do think that you could still wrap Salutation inside a <label> element, you just can't use the for attribute. I stand corrected, see the comments below. Although it's technically possible, it's not what <label> was meant for.

Nic Wortel
  • 11,155
  • 6
  • 60
  • 79
  • 2
    “no, you can't connect Salutation to the radio buttons” — incorrect. `
    ` and `` are designed for this purpose.
    – Paul D. Waite Nov 07 '12 at 16:27
  • I like the idea of using a label without associating it - it shows effort to do the right thing. But I suspect the browser would just ignore it without knowing what to associate it with. It might even expose a bug in some browser somewhere that wouldn't have happened without the dangling label tag. – GlenPeterson Nov 07 '12 at 17:54
  • 1
    @GlenPeterson: “I like the idea of using a label without associating it - it shows effort to do the right thing.” I guess, although it also shows that the person in question hasn’t looked up [what ` – Paul D. Waite Nov 07 '12 at 23:11
  • Oops, sorry Nic — when I said “the person in question” I hadn’t actually noticed that you’d suggested using label without `for`, I just though @GlenPeterson was talking hypothetically. No offence meant. – Paul D. Waite Nov 07 '12 at 23:20
  • @PaulD.Waite, none taken! You were actually right, I hadn't looked it up and I use ` – Nic Wortel Nov 07 '12 at 23:24
  • @NicNLD: phew! I would have been a bit more direct and polite if I’d noticed your suggestion. Glad the link was helpful. Most HTML tags aren’t restricted in their use like ` – Paul D. Waite Nov 07 '12 at 23:29
0

The Label's 'for' attribute corresponds to the Radio buttons ID. So...

<label for="thisRad">Radio Button 1</label>
<input type="radio" id="thisRad" />

Hope it helps.

You'd want yours to look something like this...

Salutation<br />
<label for="radMr">Mr.</label><input type="radio" id="radMr" />
<label for="radMrs">Mrs.</label><input type="radio" id="radMrs" />
<label for="radMiss">Miss.</label><input type="radio" id="radMiss" />
George
  • 36,413
  • 9
  • 66
  • 103
  • You can also wrap the radio element in a label, if you don't want to use an id. – Jørgen Nov 07 '12 at 16:25
  • 3
    I don’t think you’re quite answering the OP’s actual question. If I understand correctly, he’s asking how to mark up a label that applies to an entire set of radio buttons. – Paul D. Waite Nov 07 '12 at 16:33
  • @PaulD.Waite I read it again, you seem to be right lol. My bad. – George Nov 07 '12 at 19:10