Question

I was wondering what would happen if I'd nest 2 <label> tags, and it turns out, in all the most recent versions of all browsers, except for Opera, clicking the inner label results in only that label being clicked. Here's a demo of nested label tags' behaviour.

My question is: Are there any standards on the behaviour of browsers when handling click events in nested labels? All I could find was this MDN section about Gecko's behaviour, but I couldn't find anything about the other browsers.

The reason this is interesting to me is because if it is possible to nest label tags and still be able to select the correct input with its closest surrounding label, then it's possible to make awesome things like this. If nested label behaviour is not defined in any standards (so any browser could do whatever they want), this won't be an option at all, not even in the future. The format for any of such tabs would be:

<label>
    <input type="radio" name="1">
    <span>Shown label</span>
    <div>Contents of the tab</div>
    <!--repeat, put further identically-formatted <label>s here-->
</label>

This tab system is already possible when not nesting labels, by assigning a for attribute to the label, and an id to the input, but then you'd have to worry about unique ids for every input, and that's a lot more effort than just doing it this way. Here is another demo of that (and as you can see, it's impossible to correctly mark the label that is checked now).

<label for="tabN">
    <span>Shown label<span>
</label>
<input type="radio" name="1">
<div>Contents of the tab</div>
<!--repeat, put further identically-formatted structures here-->

PS: Please don't answer this question with "this is not what inputs and labels were designed to do!". I know that, I am just wondering about if there are any hopes for this becoming possible, including in Opera.

Was it helpful?

Solution

As you know, it is not allowed to nest label elements, as label has the following content model:

Phrasing content, but with no descendant labelable elements unless it is the element's labeled control, and no descendant label elements.

HTML5 defines what happens when a user activates interactive content:

Certain elements in HTML have an activation behavior, which means that the user can activate them. This triggers a sequence of events dependent on the activation mechanism, and normally culminating in a click event, as described below.

Step 3 of "When a pointing device is clicked" says:

Let e be the nearest activatable element of the element designated by the user (defined below), if any.

To find the nearest activatable element, an algorithm is defined:

  1. If target has a defined activation behavior, then return target and abort these steps.
  2. If target has a parent element, then set target to that parent element and return to the first step.
  3. Otherwise, there is no nearest activatable element.

This section doesn’t explicitly include the case of an invalid nesting of interactive content. I’m not sure if this algorithm also applies for invalid code (probably not). But if it would apply, only the inner label should fire.

OTHER TIPS

The html5 spec explicitly says:

The label element must not contain any nested label elements.

The way browsers deal with nested labels therefore is undefined. Beyond that, for attributes are important for accessibility and useability and should not be omitted.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top