CSS is aware of the current checked state of a checkbox input
This awareness, in combination of siblings selectors such as +
(immediate next sibling) and ~
(next sibling somewhere) allows styling different styles, for checked/unchecked states, to anything that comes after the input element. The key here is the word "after".
Basic example:
/* styles when checkbox is unchecked */
div{ border:2px solid blue; margin:10px }
div h3{ color:red; }
/* when checkbox is checked */
input:checked ~ div{ background:blue; }
input:checked ~ div h3{ color:gold; }
<input type=checkbox>
<div><h3>very<h3></div>
<div><h3>cool<h3></div>
As others have said (but is not a must) - HTML label
element allows to interact with input
elements, and in checkbox/radio
types' case - it allows to toggle their checked
state by clicking the label itself, which is "linked" to a specific input
element by the for
attribute:
<label for='x`>click</label>
and the id
attribute no the linked input:
<input type='checkbox' id='x'>
For the method to work, the input element must to be placed before whatever element(s) it is intended to control via CSS.
In real-word use cases, one would often want to use the CSS-toggling features of a checkbox over next siblings, but to obscure the fact there is a checkbox involved. The best way is by applying the hidden
attribute on the input
, which only toggles off the rendering of the input, nothing else.
The example below showcase such use case for a simple accordion component:
Practical example: Accordion
.accordion{ width: 300px; border: 1px solid silver; }
.accordion label{ display:block; padding:1em; cursor:pointer; }
.accordion label:hover{ color:red; }
.accordion > div:not(:last-child){ border-bottom:1px solid silver; }
.accordion .more{ max-height:0; transition:.5s; color:green; padding:0 1em; overflow: hidden; }
/* checked toggled */
.accordion input:checked + .content{ background:#EEE; }
.accordion input:checked + .content .more{ max-height:200px; }
<div class='accordion'>
<div>
<input type='checkbox' id='checkbox_item_1' hidden>
<div class='content'>
<label for='checkbox_item_1'>Title 1</label>
<div class='more'>
<p>This is cool<p>
<p>Yes it is</p>
</div>
</div>
</div>
<div>
<input type='checkbox' id='checkbox_item_2' hidden>
<div class='content'>
<label for='checkbox_item_2'>Title 2</label>
<div class='more'>
<p>This is also cool</p>
<p>So much fun</p>
</div>
</div>
</div>
</div>