BenLanc
BenLanc

Reputation: 2434

Why should HTML validators care about two inputs within a label, if one of them is of type hidden?

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

Answers (2)

OdraEncoded
OdraEncoded

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 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.

Upvotes: 2

MattSturgeon
MattSturgeon

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

Related Questions