You can use the :has
pseudo selector for that:

label {
display: block;
background: gray;
border:1px solid black;
margin-bottom:5px;
padding:10px;
cursor: pointer;
user-select: none;
}
label:has([type="checkbox"]:checked) {
background: yellow;
}
<div class="poll">
<label class="a"><input type="checkbox" /> Yes</label>
<label class="a"><input type="checkbox" /> No</label>
</div>
If you need browser backward-compatibility support, here's a trick:
label {
display: block;
background: gray;
border:1px solid black;
margin-bottom:5px;
padding:10px;
cursor: pointer;
overflow: hidden; /* Important so the outline won't overflow */
user-select: none;
}
label :checked {
outline: 9999px solid yellow;
}
<div class="poll">
<label><input type="checkbox" /> Yes</label>
<label><input type="checkbox" /> No</label>
</div>
OP asked me in the comments for a solution tailored for a hidden checkbox.
All that is needed is to use the hidden
attribute on the input.
Never use CSS display: none
to not render an input element.
It is preferable to use the designated attribute.
Note that this also has a bug in Firefox. Below is a Firefox-hack to overcome it.
label {
display: block;
background: gray;
border:1px solid black;
margin-bottom:5px;
padding:10px;
cursor: pointer;
user-select: none;
}
label:has([type="checkbox"]:checked) {
background: yellow;
}
<div class="poll">
<label><input type="checkbox" hidden /> Yes</label>
<label><input type="checkbox" hidden /> No</label>
</div>
Firefox-supported solution:
Extract each input
to be above the label
element, and use a unique id
attribute on each input
element, and a matching for
attribute on each label
:
label {
display: block;
background: gray;
border:1px solid black;
margin-bottom:5px;
padding:10px;
cursor: pointer;
user-select: none;
}
:checked + label {
background: yellow;
}
<div class="poll">
<input type="checkbox" id='poll-1' hidden/>
<label for='poll-1'>Yes</label>
<input type="checkbox" id='poll-2' hidden/>
<label for='poll-2'>No</label>
</div>