How to Make Entire Custom Checkbox/Div Clickable -- Not Just the Label + Input

Solution 1:

The answer is quite symple: you don't need an additional div-element. Actually you can place a label-element wherever you want and associate it with an input-element of your choice.

You do so by giving the input-element a id-attribute and associate the label-element with a corresponding for-attribute.

eg: <input id="my-input-id">[...]<label for="my-input-id">Label Text</label>)

  • A <label> can be associated with a control either by placing the control element inside the element, or by using the for attribute. Such a control is called the labeled control of the label element. One input can be associated with multiple labels.
  • Labels are not themselves directly associated with forms. They are only indirectly associated with forms through the controls with which they're associated.
  • When a <label> is clicked or tapped, and it is associated with a form control, the resulting click event is also raised for the associated control.

Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label

label {
    display:block;
    border:solid 1px gray;
    line-height:40px;
    height:40px;
    width: 250px;
    border-radius:40px;
    -webkit-font-smoothing: antialiased; 
    margin-top:10px;
    font-family:Arial,Helvetica,sans-serif;
    color:gray;
    text-align:center;
}

input[type=checkbox] {
    display: none;
}

input:checked + label {
    border: solid 1px red;
    color: #F00;
}

input:checked + label:before {
    content: "\2713 ";
}


/* new stuff */
.check {
    visibility: hidden;
}

input:checked + label .check {
    visibility: visible;
}

input.checkbox:checked + label:before {
    content: "";
}
<input id="lists[Travel]" type="checkbox" name="lists[Travel]" />
<label for="lists[Travel]">Travel with jump</label>

<!-- alternatively avoid jumps between text of state checked and unchecked -->

<input class="checkbox" id="lists[new]" type="checkbox" name="lists[new]" />
<label for="lists[new]"><span class="check">✓</span> Travel without jump</label>

In addition you can fiddle around with the display: block of the <label>. But this should be quite simple by giving it float: left, display: inline-block or whatever to get the desired elements float.

CODEPEN

Solution 2:

Here's a one way to achieve this:

<div onclick="this.querySelector('input[type=checkbox]').click()">
  <input type="checkbox" style="pointer-events:none">
  <span>Label</span>
</div>

Or if you give the checkbox an id:

<div onclick="abc.click()">
  <input id="abc" type="checkbox" style="pointer-events:none">
  <span>Label</span>
</div>

You need pointer-events:none in this appraoch because otherwise a double-click (causing check and uncheck) happens when you click on the checkbox directly.