4

Consider the following markup:

<label>
  <input type="hidden" name="likes_bacon" value="no" />
  <input type="checkbox" name="likes_bacon" value="yes" />
  I like bacon
</label>

The W3C HTML validator will raise an error against this markup as the label contains more than one input, which is technically invalid.

My question is two fold: why should a validator care, since the first is hidden? User agents (including screen readers - I've checked) do not make any indication that the hidden field exists, and it's quite common/useful for frameworks to render checkboxes with an accompanying hidden input with the same name in order to always pass through a default value in the form submission in cases where the form is submitted with the checkbox unchecked. The hidden input is also immutable since it is not really a user-editable form control.

Secondly, aside from the possibility of an error showing up in browser consoles and failing validation, is there any harm in doing this? I can't think of a single reason other than "you're not supposed to"!

I guess this leads on to a wider point that perhaps input type="hidden" is a misnomer, as it is not really an input at all!

I'm well aware that it's entirely possible to move the inputs outside of the label and reference the checkbox by id with the for attribute.

Loosely related: Two input fields inside one label

Community
  • 1
  • 1
BenLanc
  • 2,344
  • 1
  • 19
  • 24
  • 1
    Conversely, why should there be an exception in the spec for hidden input fields? – JJJ Aug 16 '13 at 11:11
  • In fact, it's enough to move only the hidden input outside of the `label`. Inputs still will work together since they share the same `name`, but only the checkbox will be linked with the `label` and will be activated when the user clicks the `label`. – Ilya Streltsyn Aug 16 '13 at 11:20
  • 2
    This seems to be more of an issue with the HTML 5 drafts and the experimental validators checking against them, rather than a practical problem with authoring or programming. – Jukka K. Korpela Aug 16 '13 at 11:50
  • I can see a problem of a whole different kind with this HTML... I mean, those names! – Mr Lister Aug 16 '13 at 12:57
  • @Juhana I am of the opinion that there probably should be an exception for hidden inputs since they are by nature not directly user-editable form controls, see final point regarding "input" *perhaps* being a bit of a misnomer – BenLanc Aug 16 '13 at 12:59
  • @IlyaStreltsyn Sure, but there's a lot to be said for legibility and ease of understanding by having them directly adjacent to eachother – BenLanc Aug 16 '13 at 13:00
  • 2
    I'm failing to see a valid use case here. Could you expand on how you would use such a construct? – steveax Aug 17 '13 at 04:27
  • @steveax This came up because the forms part of Spring was rendering a hidden input alongside every checkbox in order to ensure a default value was always passed for every checkbox input. In the example I use, the user agent will submit "no" for the "likes_bacon" input *unless* it's ticked. – BenLanc Aug 19 '13 at 14:15

2 Answers2

2

Why the W3C validator says that is not valid? Because is not valid! Plain and simple. The HTML specification itself says:

The label element may contain at most one descendant input element, button element, select element, or textarea element.

Since the spec says it is invalid, the validator will say it is invalid.

Now, the reason as to why the specification says so is because clicking on a label focuses the interactive element associated to it. When an element has focus it can receive keyboard input.

By unspoken user interface standards, you can only type in one text box at a time. Since you can only type in one text box, only one form control needs to receive keyboard input at any time. Because of that, there is only one interactive HTML element with focus at any time.

There would be no point focusing two elements at once with a label, since there can only be one receiving the keyboard input.

There is also no point putting a hidden input inside a label, by the way. Since hidden inputs are not manipulated by the user, there is no point giving the keyboard input to them.

OdraEncoded
  • 3,064
  • 3
  • 20
  • 31
  • That's precisely my point; hidden inputs are not interactive, ergo I'm of the opinion that it is an unnecessary constraint which has, as far as I'm aware, zero side effects if ignored. And the reason it's within the label is because certain MVC frameworks tend to render a hidden input with the same `name` as an immediately succeeding checkbox. – BenLanc Sep 04 '13 at 10:46
  • @BenLanc I'm not sure you understand. The label element is for interaction. For interaction it must be visible. You can't click an invisible element. Thus there is no point in either putting an interactive input there or an invisible input there. – OdraEncoded Sep 04 '13 at 12:17
  • @BenLanc I think the simple solution here is to report this to these frameworks as a bug. – MattSturgeon Sep 06 '13 at 05:18
  • @OdraEncoded +1 for a nice, simple and clear answer that gets straight to the point. – MattSturgeon Sep 06 '13 at 05:19
1

Basically, the reason this throws a validation error is because a label element must only be associated with one input element (of any type). Because of this only one "form control" may be within a label just like only one I'd can be listed within a for attribute. Semantically an input of type hidden is still a "form control" and can therefore have a label associated with it. The fact that is not visible is a matter for the default CSS imposed by the browser and so while it may not be a good authoring practice it is entirely possible to have

<style scoped>
input[type=hidden] {
    display: inline-block;
    visibility: visible;
}
</style>
<label>
    Hidden input:
    <input type="hidden" value="Peek-a-boo!"/>
</label>

You see, an input[type=hidden] is still and input, and therefore still a form control, and therefore it is still possible to assign it a label (at least according to the specs - there may be browser bugs with this). Because it is a form control, it cannot sit alongside another form control within a label. Simple as. As far as I am aware, there is nothing in the spec that says a hidden type input cannot have a label reference it.

In the case outlined in the question, a user agent would correct the error by only associating the label with the non-hidden input, but a less well known UA might choose to reference either the first or last "form control" which might not be the author's intention.

From the specification:

The LABEL element may be used to attach information to controls. Each LABEL element is associated with exactly one form control.

The for attribute associates a label with another control explicitly: the value of the for attribute must be the same as the value of the id attribute of the associated control element. More than one LABEL may be associated with the same control by creating multiple references via the for attribute.

In your specific case, you could simply move the hidden input out of the label like so:

<input type="hidden" name="likes_bacon" value="no" />
<label>
  <input type="checkbox" name="likes_bacon" value="yes" />
  I like bacon
</label>
MattSturgeon
  • 452
  • 4
  • 11
  • 1
    Why would a browser try to associate an `input[type="hidden"]` with anything? It should also never be explicitly associated with a label so I fail to see a problem except in the length of HTML5 specs – FelipeAls Aug 18 '13 at 09:09
  • @FelipeAls you seem to be misinterpreting this a little: a `label` can have a reference to one `input`. Technically speaking, an `input` doesn't have **any** references to any `label`s – MattSturgeon Aug 20 '13 at 08:14
  • From an accessibility point of view (WCAG 2.0), the role/purpose of an `input[type="text"]` must be explicited some way or another. One of the Techniques (not mandatory) is to associate a label, another way is to have a title attribute on the input. And I know no other way to explicit its role (especially not `@placeholder` but I digress ^^). But a hidden input? It has no role in the understanding of content. – FelipeAls Aug 20 '13 at 16:51
  • Yes, from an accessibility perspective I can understand what you are saying (unless some idiot was to make hidden inputs visible using CSS - why? I don't know!). I've answered the question of why the validator cares about multiple `inputs` (regardless of type) within `labels` - the reason being because the spec says so (of course). If the question was reworded as "why the spec cares about hidden inputs within labels" I would probably say for the sake of simplicity. Also I apologise for the presumptuous nature of my last comment - I probably shouldn't be allowed to communicate late at night! – MattSturgeon Aug 21 '13 at 14:47