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!
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: 'âś”';
}
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;
}
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!