This is a particularly useful little trick which makes use of CSS’s sibling
selector (~
) as well as the pseudo-class :checked
on an HTML checkbox.
The purpose behind this is to create buttons that can be used to toggle CSS "states" without the need for additional javascript.
The following demo & code demonstrates this principle in action. Click the button to see it working.
See the Pen the “Checkbox Hack” trick by Robin Metcalfe (@solarisedesign) on CodePen.
This works by using the sibling selector, ~
to target an element on the same level as the checkbox, and apply one particular set of rules based on the status of the :checked
pseudo-class. As you can see from the code, you can also use :not(:checked)
to target the inactive state.
Using the following code as the basis,
.checkbox:checked ~ .target .descendant {
/* Apply some CSS to .descendant in .target
whenever the checkbox is _active_ */
}
.checkbox:not(:checked) ~ .target .descendant {
/* Apply some CSS to .descendant in .target
whenever the checkbox is _inactive_ */
}
you can see how this allows you to control the state of any descendant of the .target
element, opening up possibilities for many complex interactions. Another code demo on my site, Impossible Isometrics has been built using this as the basis for the button interactions.
It’s also required to include the label
element, otherwise Firefox doesn’t render this method properly.
There are some limitations to this. It does restrict you in the structure of your HTML. The checkbox does need to live on the same level and within the same parent element as the element you wish to "control"
Internet Explorer 8 also doesn’t support the :checked
pseudo-class. This is something you could add a Javascript workaround for though, using something like selectivizr
It also gets quite complex if you’re trying to perform complex animations, and you might be better off using Javascript for more complicated things.
However, it is useful for things like responsive menus on websites, or other situations where you need some complex functionality without relying on Javascript.
As a fun extra exercise (woo! fun extra work. yay) see if it’s possible to do something similar to the above but with the select
element, to allow for multiple states
Robin is the dedicated developer behind Solarise.dev. With years of experience in web development, he's committed to delivering high-quality solutions and ensuring websites run smoothly. Always eager to learn and adapt to the ever-changing digital landscape, Robin believes in the power of collaboration and sharing knowledge. Outside of coding, he enjoys diving into tech news and exploring new tools in the industry.
If you'd like to get in touch to discuss a project, or if you'd just like to ask a question, fill in the form below.
Send me a message and I'll get back to you as soon as possible. Ask me about anything - web development, project proposals or just say hi!