60

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?

loopasam
  • 3,027
  • 2
  • 21
  • 22
sqwk
  • 1,506
  • 2
  • 12
  • 13
  • Why do you need to put input inside the label?? Why not to – Alex Dn Jan 25 '12 at 14:30
  • 1
    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 Jan 25 '12 at 14:36
  • 4
    @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 Feb 18 '16 at 04:54
  • Related: [When a label only has a button, a button click does not (fully?) trigger the label](http://stackoverflow.com/questions/31944554/when-a-label-only-has-a-button-a-button-click-does-not-fully-trigger-the-lab) – BoltClock Feb 18 '16 at 05:01
  • BTW your type of html isn't working on my iPad. The second input can't be accessed. – Luke Wenke Jul 19 '16 at 01:25

8 Answers8

79

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:

tagurit
  • 494
  • 5
  • 13
David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • 3
    It seems you can also use [labelledby](https://www.w3.org/TR/WCAG20-TECHS/ARIA9.html#ARIA9-ex2) (though I'd still opt for your solution). – Phil D. Nov 28 '16 at 22:34
39

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

Diego Jancic
  • 7,280
  • 7
  • 52
  • 80
  • The hidden label solution is clever, elegant, and seems to fit the best with standard practice. Don't forget to change the visibility attribute in the style-sheet to hidden for that class! ;) – user7778287 Jan 09 '20 at 07:51
  • 2
    @user7778287 do not use the visibility attribute. Check for https://webaim.org/techniques/css/invisiblecontent/#techniques for more information. Specifically: `.hidden {position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;}` – Diego Jancic Jan 09 '20 at 12:30
  • "display:none; or visibility: hidden; These styles will hide text from all users. The text is removed from the visual flow of the page and is ignored by screen readers." Worth noting. – user7778287 Jan 10 '20 at 00:42
  • I was thinking more of option 3 – Royer Adames Nov 15 '21 at 18:54
  • If there's enough context for sighted users to understand the purpose of the ``s, using an `aria-label` is [W3's recommended way](https://www.w3.org/TR/WCAG20-TECHS/ARIA14.html) of handling this sort of situation. – Zach Saucier May 10 '23 at 21:51
21

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.

Community
  • 1
  • 1
user1448926
  • 399
  • 2
  • 7
  • 4
    This answer should be marked as the correct answer. – Martijn van de Rijdt Jan 31 '20 at 21:28
  • 1
    Thanks for pointing this out. Other answers should have mentioned it too. However, I don't think the other answers are actually wrong. It is syntactically allowed - but it doesn't carry the meaning of labelling all the inputs within. Labelling multiple inputs is what the questions is about, not just valid html syntax. – Jordan Shurmer Apr 06 '21 at 11:40
  • 1
    I don't think that's correct anymore (as of Sept 2021). The content model disallows labelable elements (input, etc...) except for the element's particular labeled control. I quote the content model: "Phrasing content, but with no descendant labelable elements unless it is the element's labeled control, and no descendant label elements." The second paragraph that you quoted was revised to indicate that the label does nothing for other interactive elements that may be it's descendant. I.E. 'Don't do anything as fallback behavior for invalid content.' – Jimmy Sep 22 '21 at 03:27
  • Multiple labelable elements within a ` – Quolonel Questions Feb 02 '23 at 14:43
3

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.

zysoft
  • 2,268
  • 1
  • 16
  • 21
  • 2
    You refer to an outdated specification. It is correct to set multiple lableable elements inside a label (https://www.w3.org/TR/html5/sec-forms.html#the-label-element) but only the first of these is actually labeled. – wortwart Jun 11 '18 at 09:12
2

How about this:

<label> Range from <input name='min_value'> </label>
<label> to <input name='max_value'> </label>
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • 1
    Not a good idea, as it requires context. The label only makes sense for forward navigation. – H.B. Oct 14 '20 at 13:24
1

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.

Martin Zvarík
  • 2,120
  • 22
  • 27
1

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'
gowthami
  • 155
  • 1
  • 10
  • I could not find where in the linked spec it says that multiple inputs can be put inside in the same label.... – Jonah May 15 '22 at 06:32
  • 1
    @Jonah: _"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."_ – phk Apr 26 '23 at 08:54
-5

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.

kolin
  • 2,326
  • 1
  • 28
  • 46
  • 2
    No it's perfectly fine to put an input inside a label. In a perfect world, the for/id association shouldn't be necessary with these so-called implicitly associated labels because it would be so obvious that the corresponding label is the parent of this input. In the real world, screen readers didn't manage to get that for so long that it's mandatory to use matching for/id attributes. – FelipeAls Jan 29 '12 at 12:03
  • 1
    `` is an example of using the label element for help text displayed on the right of the input but read by screen readers at the right moment: before the ((partially-)blind) user has a chance to type sth in the input. It's not so helpful to help him after he typed sth in the input ;) – FelipeAls Jan 29 '12 at 12:12
  • IRL, a label doesn't contain what it is for. A jar of pickles isn't contained inside the label indicating that it's a jar of pickles. The label simply states that it's for that jar of pickles. I can move that label anywhere but it is still for that jar of pickles. The same goes for HTML forms. IMO, a label shouldn't contain the control that is labels. It should simply point to that particular control. What if I wanted to remove the label (for some reason I can't yet think of) via JavaScript? I'd be removing the control as well! I can throw away that label and the jar of pickles is still there. – Tyler Crompton Apr 02 '12 at 09:18
  • 3
    "IRL", as in "In Real Life"? HTML semantics are not intended to reflect the physical world. There are two associations a control can have with a label: implicit (label content), or explicit ("for="). This is defined and accepted usage (if not favored) in the spec itself, which is the only relevant space in this discussion. –  Jun 10 '14 at 17:55
  • @FelipeAls could you expand on your claim that screen readers properly support the for attribute but not nesting of inputs within labels, and provide either a source for it or instructions on how to test and confirm it? Yours is the first mention of this issue I've ever seen, and I can't find any further discussion of the point on Google. – Mark Amery Apr 08 '15 at 14:27