I found some really weird things I can't explain. I tried making custom checkboxes using CSS by following this codepen.
I copied most of it, but for some reason it didn't work. After checking my code, I noticed that I didn't use the id
attribute on my checkbox and neither did I have a for
attribute on my label.
For example:
/* Base for label styling */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
position: absolute;
left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
position: relative;
padding-left: 25px;
cursor: pointer;
}
/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
content: '';
position: absolute;
left:0; top: 2px;
width: 17px; height: 17px;
border: 1px solid #aaa;
background: #f8f8f8;
border-radius: 3px;
box-shadow: inset 0 1px 3px rgba(0,0,0,.3)
}
/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
content: '✔';
position: absolute;
top: 0; left: 4px;
font-size: 14px;
color: #09ad7e;
transition: all .2s;
}
/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
opacity: 0;
transform: scale(0);
}
[type="checkbox"]:checked + label:after {
opacity: 1;
transform: scale(1);
}
/* disabled checkbox */
[type="checkbox"]:disabled:not(:checked) + label:before,
[type="checkbox"]:disabled:checked + label:before {
box-shadow: none;
border-color: #bbb;
background-color: #ddd;
}
[type="checkbox"]:disabled:checked + label:after {
color: #999;
}
[type="checkbox"]:disabled + label {
color: #aaa;
}
/* accessibility */
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
border: 1px dotted blue;
}
/* hover style just for information */
label:hover:before {
border: 1px solid #4778d9!important;
}
body {
font-family: "Open sans", "Segoe UI", "Segoe WP", Helvetica, Arial, sans-serif;
color: #777;
}
<form action="#">
<p>
<input type="checkbox" />
<label>Red</label>
</p>
<p>
<input type="checkbox" id="test2" checked="checked" />
<label for="test2">Yellow</label>
</p>
<p>
<input type="checkbox" id="test3" checked="checked" disabled="disabled" />
<label for="test3">Green</label>
</p>
<p>
<input type="checkbox" id="test4" disabled="disabled" />
<label for="test4">Brown</label>
</p>
</form>
For some reason, this custom styled checkboxes only work if the for
and id
attribute are specified. If I leave them away, I can no longer check/uncheck the checkbox. If you look at the snippet above, you will notice that you can't check/uncheck the "Red" checkbox, but you can check/uncheck the yellow one. I tried it on both Google Chrome and Mozilla Firefox (on Ubuntu), same behavior in both browsers.
I thought those attribute where pure semantics, but it seems that it causes some other things to happen as well.
I'm happy I got it to work, but I'm still confused and I don't know why it doesn't work without the attributes.
The for
attribute in the label tells the browser to move the focus to the input whose ID is identical to the value. This makes the label a labelled control for that input element. This question has also been addressed previously on SO: What does "for" attribute do in HTML <label> tag?
When you remove the for
attribute on the <label>
element or the id
attribute on the <input>
element, you are decoupling both elements and therefore preventing the click event on the <label>
from propagating into a focus + click event on the corresponding checkbox.