48
votes

Consider the following:

<label>Range from 
    <input name='min_value'/> to
    <input name='max_value' />
</label>

Is this semantically correct since the W3C recommendations state that a label is associated with exactly one form control?

Clicking into the second input shifts focus immediately to the first input? Can this be prevented?

How would one markup a min/max input combination to show that two inputs belong together?

8
Why do you need to put input inside the label?? Why not <label>Range from </label> <input name='min_value'/> to <input name='max_value' />Alex Dn
Semantically, you need a for attribute on your label which links to one input's id (which should be unique across the scope of the page).MetalFrog
@MetalFrog: Nesting the control in the label will provide the necessary semantics - adding a for attribute to the label in that situation is redundant. The for attribute is only necessary when the control appears elsewhere. That said, it can be useful to specify a for attribute anyway to ensure that you're associating the label with the right control, as a validation error will be raised when a conflict is found: "Any input descendant of a label element with a for attribute must have an ID value that matches that for attribute."BoltClock
BTW your type of html isn't working on my iPad. The second input can't be accessed.Luke Wenke

8 Answers

67
votes

No, it's not correct (since, as you note, a label is associated with exactly one form input).

To label a group of inputs that belong together, use a <fieldset> and a <legend>:

<fieldset>
  <legend>Range</legend>
  <label for="min">Min</label>
  <input id="min" name="min" />

  <label for="max">Max</label>
  <input id="max" name="max" />
</fieldset>

References:

31
votes

As the accepted answer states, that's not correct, however I think there are better ways to do it.

Accessible alternatives:

Option 1 (using the aria-label attribute):

Range:
<input ... aria-label='Range start' />
<input ... aria-label='Range end' />

Option 2 (using hidden label tags):

<label for='start'>Range start</label>
<input type='text' id='start' />

<label for='end' class='hidden'>Range end</label>
<input type='text' id='end' />

Where the .hidden class is only readable by screen readers.

Option 3 (using aria-labelledby attributes):

<label id='lblRange'>Range</label>
<input type='text' id='start' aria-labelledby='lblRange' />
<input type='text' id='end' aria-labelledby='lblRange' />

Advantages of option #1: Each input has a good description that other suggestions (such adding a "to" label) do not. Options #2 and #3 might not be the best for this specific case, but worth mentioning for similar cases.

Source: http://webaim.org/techniques/forms/advanced

15
votes

I see many answers saying it is wrong to put 2 inputs inside a label. This is actually a wrong statement in html5. The standard explicitly allow it: http://www.w3.org/TR/html5/forms.html#the-label-element

If the for attribute is not specified, but the label element has a labelable element descendant, then the first such descendant in tree order is the label element’s labeled control.

If a label element has interactive content other than its labeled control, the activation behavior of the label element for events targeted at those interactive content descendants and any descendants of those must be to do nothing.

However, Safari does not respect the html5 standard here (tested on iOS 11.3). So, someone that wants to be compatible with Safari must use workarounds here or wait until Apple fixes its browser.

3
votes

According to this - label can contain only one input as it should be associated with only one control. Putting input inside the label means elimination of for attribute (automatic linking).

So you should either put single input into label or specify for attribute which points to input id and don't put input into label.

2
votes

How about this:

<label> Range from <input name='min_value'> </label>
<label> to <input name='max_value'> </label>
1
votes

1 LABEL = 1 INPUT !!!

If you put 2 INPUTS inside a LABEL, it will NOT work in Safari (and iPad and iPhone)... because when you click inside LABEL it automatically focuses the first INPUT... so the second input is impossible to type to.

0
votes

I see many answers saying it is wrong to put 2 inputs inside a label. This is actually a wrong statement in html5. The standard explicitly allow it: http://www.w3.org/TR/html5/forms.html#the-label-element

<label id='dobRange'>DOB between</label>
<input type='text' id='start' aria-labelledby='dobRange' />
<input type='text' id='end' aria-labelledby='dobRange' />

in haml:

= f.label :dob_range
= f.search_field :dob_gteq, 'aria-label': 'dob_range'
= f.search_field :dob_lteq, 'aria-label': 'dob_range'
-4
votes

i don't think you should be putting the input field inside the label control.

<label for="myfield">test</label><input type="text" id="myfield" name="myfield />

the label is just that, a label for something.