User Friendly + Interactive Custom CSS Checkboxes

Last Updated Monday, 28 December 2020

Over the last few days I've been working on creating some creative checkboxes that use pseudo elements, SVG animations, and a few other techniques. For some, I used a little bit of Javascript to allow for more options.

A big annoyance for me is the fact that checkboxes return a value of on and off, so for these I've created a hidden input which returns a value of 1, 0, or a number inbetween for some of the checkboxes which have multiple options. That means you can access the checkbox value directly from this hidden input with class .hidden-value.

As well, I have put the value of the checkbox onto the .checkbox-container element, under the data-value attribute, giving you a lot of flexibility.

Click for Demo

Some thoughts

Checkboxes and input forms are one of the various screens we use to gather information from users. The user interaction with these are often quite boring, but they don't have to be. For list apps and projects that depend on checkboxes, how a checkbox is displayed is very important. The checkboxes here cover the main use cases involving checkboxes.


For more complex checkboxes you find on the web, they often come with CSS classes like .big or .medium. With the variety of screens websites serve today, this can actually be a hinderance rather than being particularly useful.

To avoid that, I have made all of these checkboxes with em units. That means your checkbox can be any size you like, you just have to change the font-size on the parent element. In the files for these checkboxes, that might mean changing the font size on .list-item. I have done it on the HTML tag, but feel free to change that. This means you can adjust them easily for mobile. As a quick example:

css Copy
@media screen and (max-width: 900px) { html { font-size: 30px; /* Very big buttons */ } }

This takes the fuss out of having to depend on specific CSS classes, and makes everything relatively straight forward.


Something I did for some of these checkboxes was to use an SVG path and animating that. What surprised me was I didn't need any Javascript for that, so I'll be covering that in another tutorial on how to create the hand drawn SVG effect I got here. Stay tuned.


Although the majority of these checkboxes work fine without Javascript, I added some to get a few additional features. For example, some checkboxes have multiple options. One might have 4 settings, for example. In these cases, I wanted to set up custom values - instead of a 1 or 0, 1/3 of the way along might produce a 0.33. Of course this isn't possible with pure CSS, but it only applies to a few checkboxes.

Secondly, I wanted to update the value of the hidden input as I explained in the first paragraph. Doing this with Javascript was a relative breeze.

Usability and Accessibility

A key part of any design is usability and accessibility. The ability to tab through a page is useful, not only to certain accessibility programs, but also to me that one time I spilt coffee all over my keyboard, and the tab key was the only one which worked.

So for these checkboxes, I have added this, not by hiding the input entirely, but moving it way off screen. That means the input is still focusable, and we update the label or element next to it when it is focused upon. That allows us to tab through, and provide focus events for our custom checkboxes:

css Copy
input[type="checkbox"] { position: absolute; right: 999999px; } input[type="checkbox"]:focus + label { /* Our focus CSS goes here */ }

CSS Variables

A big thing I made use of here as well were CSS variables. All the colors relating to the checkbox are defined by CSS variables. That means you can update the CSS variable colors, and update every checkbox's color as well. This is quite useful - rather than having to individually change checkbox appearance, we can simply update a few key variables. I have covered how to update CSS variables with Javascript here.


In summary, I hope these effects prove useful in one of your future projects. I have put the demo and code on CodePen, and the code is available from the Git Repo below. Enjoy!