Fancy checkbox using CSS only

by John Folley on April 18 2013

Styling checkboxes

Form elements have always been difficult to style up as we want. However thanks to the sibling selector and the checkbox trick, at least the checkbox element is easy to 'style'.

Some solutions attempt to mimick the behaviour of the checkbox using javascript and image replacement. Effectively this involves hiding the checkbox, replacing instead with a fancy checkbox image. Click events are on the image element as well as hover events perhaps to fully mimick the checkbox.

This works, however there are a few issues with this: javascript is required and while most users will have javscript enabled, there's an overhead in the added javascript required. This will be an extra HTTP request, not including the images replaced.

Also, javscript processing and events is quite costly. For a single checkbox on a page, it doesn't matter much but in a table of dozens of rows with one or more checkboxes this starts to slow down the page.

There is however a different solution: using the "checkbox" hack, we can style checkboxes using CSS only.

The code first

<div class="well">
    <label class="checkbox fancy-checkbox">
        <input type="checkbox" runat="server" />
        <i class="icon-check-empty">
        <i class="icon-check">
        This is a checkbox

.fancy-checkbox i.icon-check,
.fancy-checkbox i.icon-check-empty{
    float: left;
    margin-left: -20px;
    vertical-align: bottom;

.fancy-checkbox input[type=checkbox],
.fancy-checkbox i.icon-check,
.fancy-checkbox [type="checkbox"]:checked ~ i.icon-check-empty{
.fancy-checkbox i.icon-check-empty,
.fancy-checkbox input[type=checkbox]:checked ~ i.icon-check{

How does it work?

The above code uses Bootstrap and Font Awesome to create the two states: checked and unchecked. These are represented by the two i elements.

The trick involves two factors. When clicking on a label associated to the checkbox, the checkbox state is updated. We can click on the label and although the checkbox is hidden, it will have updated the checkbox.

The following factor is that it is possible to style elements based on their siblings, however the siblings need to precede the element. This is the ~ selector.

We can therefore apply styling (simple display rules) to the icons based on the sibling checkbox state.

Here's an example of this working:

Tags: web-dev
comments powered by Disqus