Home > front end >  Button inside label triggers (sometimes double trigger \ double click)
Button inside label triggers (sometimes double trigger \ double click)

Time:07-22

There was similar question, but i don't have enough reputation to post an answer, so i'm doing it as "new question"

the problem is:

<label>
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input>
</label>

If you will click on anywhere inside the label - it will trigger first button, not second button, not focus into input

thats because label triggers whatever it finds first inside it

so if you'll click on something 2 button - you will have 2 clicks: label will trigger first button and you (as user) will trigger second button

and it is actually easy solvable

<label for="unique">
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input id="unique">
</label>

that way label will always know what exactly to trigger

CodePudding user response:

General advise is “Don't place interactive elements such as anchors or buttons inside a label.“

While using the for attribute might work around the part of the problem with clicking the label, it poses other issues.

<label for="unique">
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input id="unique">
</label>

The HTML Standard does not allow additional interactive elements in a <label> to begin with:

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

So this might work today, but since it’s not supported by the standard, browser vendors are free to change behaviour.

The HTML element represents a caption for an item in a user interface.

The main purpose of a label is to provide an accessible text to an input, so that users know what to enter, even when using assistive technology like screen readers or voice control. The label’s text contents will therefore be used to label the input, taking into account all included texts. It will be captioned “something 1 something 2”.

This is not very good, so my advise would be to not rely on the for attribute to fix the click issue, but to separate it and implement the click behaviour yourself.

Using a <fieldset> will have the advantage of the controls being grouped for assistive technology as well, so entering or leaving the group with the focus will be announced.

focusInput = e => e.currentTarget.querySelector('input').focus();
action = e => {
  alert('Action!');
  e.stopPropagation();
}
<fieldset onclick="focusInput(event)">
  <legend>Group Title</legend>
  <button type="button" onclick="action(event)">something 1</button>
  <button type="button" onclick="action(event)">something 2</button>
  <br>
  <label>
    Input Label
    <input>
  </label>
</fieldset>

Note that no keyboard handlers are bound to the fieldset, as this would once again be confusing to keyboard users.

  • Related