3 Ways to Customize HTML Checkboxes with CSS3

Have you ever wanted to change the default look and feel of your checkboxes? To be honest, it looks a little odd on a modern website.

Today I'm going to show you 3 different ways you can customize your checkboxes with CSS3. No JavaScript required, but you might want to read more about CSS adjacent, before and checked selectors before we begin.

Let's get started!

start

1. Label + Custom Content

For this we're going to need an input of type checkbox, followed by a label with a for attribute to bind the label to the input with the corresponding id.

<div class="form-control">
    <h3>Simple checkbox with custom content</h3>
    <input class="chb-1" id="chb-1" type="checkbox" />
    <label for="chb-1">Checkbox 1</label>
</div>

It also has a title and everything is surrounded by a div with a class of form-control. You can use that to add some styling in the future, most probably for some margin if you have multiple div's...

Now to the fun part let's add the CSS. The first thing we need to do is to hide the default checkbox. Don't worry, we used the for attribute in the label and it will trigger the check event whenever someone clicks the label tag (or what's inside).

.chb-1 {
    visibility: hidden;
}

With the help of the adjacent selector, we can target the label which comes right after the input to style it:

.chb-1 + label {
    position: relative;
    padding-left: 5px;
}

By setting the position to relative we can position any children of the element exactly where we want it to. As we don't have any tag children for the label, we'll use the ::before selector to create a small rounded box:

.chb-1 + label::before {
    background-color: #16a085;
    border-radius: 3px;
    content: ' ';
    width: 16px;
    height: 16px;

    position: absolute;
    top: -1px;
    left: -20px;
    padding: 2px 1px 0;

    /* For styling the content text, following next*/
    font-size: 12px;
    text-align: center;
}

If you check out now, you'll see a green box right next to the label's text. The only thing we need to do now is the change the content when the checkbox is checked using, of course, the :checked selector:

.chb-1:checked + label::before {
    color: white;
    content: '✔';
}

voila

How simple was that? Now you can customize it as much as you want. You can either changed the box's background color, the content, width, height, border, everything!

The only drawback for this approach is that sometimes you might want to have a more customized checkbox, and for that you would want to use a background image.

2. Label + Background images

The approach would be pretty similar, but instead of the background color and border, you'll have a background-image property:

HTML:

<div class="form-control">
    <h3>Simple checkbox with custom content</h3>
    <input class="chb-2" id="chb-2" type="checkbox" />
    <label for="chb-2">Checkbox 1</label>
</div>

CSS:

.chb-2 {
    visibility: hidden;
}

.chb-2 + label {
    position: relative;
    padding-left: 5px;
}

.chb-2 + label::before {
    background-image: url('unchecked.png');
    background-position: center center;
    background-size: cover;
    content: ' ';
    width: 25px;
    height: 25px;

    position: absolute;
    top: -5px;
    left: -23px;
}

.chb-2:checked + label::before {
    background-image: url('checked.png');
}

As you can see, we select a background image for the label's ::before selector, and when the input is checked, we change it to another image (the checked version). Also, using the background-position property we can center the image and make the image fill the entire available space with background-size set to cover.

Of course, you can use any images you want. The sky is the limit!

3. Label + Transform + Transition

For this example, we're going to create another absolute positioned box:

HTML:

<div class="form-control">
    <h3>Simple checkbox with custom content</h3>
    <input class="chb-3" id="chb-3" type="checkbox" />
    <label for="chb-3">Checkbox 1</label>
</div>

CSS:

.chb-3 + label {
    position: relative;
    padding-left: 5px;
}

.chb-3 + label::before {
    border: 2px solid #3498db;
    content: ' ';
    width: 16px;
    height: 16px;

    position: absolute;
    text-align: center;
    top: -2px;
    left: -20px;
}

Nothing new so far, but, here comes the fun part. Let's to use the transform property to rotate the box 40deg, decrease the width and hide the top and left border by setting the color to transparent:

.chb-3:checked + label::before {
    top: -5px;
    left: -15px;
    width: 6px;
    height: 14px;

    border-top-color: transparent;
    border-left-color: transparent;
    transform: rotate(40deg);
}

At the end, by adding a transition property we can animate the rotation and the border color to give it a nice effect:

.chb-3 + label::before {
    transition: all 0.1s ease-in, border-color 0.05s ease-in;
}

that's all folks

Make sure you check out the code on Codepen where I added some more styling and minimized the CSS used for all 3 checkboxes.

Did you enjoy the post? Do you have anything you'd want to add? Let me know your thoughts via email or twitter DM!

Tagged with html5, css3, animation