Reputation: 2434
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
Upvotes: 4
Views: 580
Reputation: 3134
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 descendantinput
element,button
element,select
element, ortextarea
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.
Upvotes: 2
Reputation: 450
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>
Upvotes: 1