Replace HTML checkbox with images

Native HTML checkboxes look like something:

Native HTML checkboxes in Google Chrome

The checkboxes are not always displayed in the same way depending on the browser. Moreover, they may not match the graphic design of the website. This is why it is sometime usefull to replace the native checkbox with custom images.

Here is the expected result:

The images

Of course, we need images to replace the checkbox. I selected the following images from the awesome Friconix icon provider.

Images for HTML checkboxes replacement

HTML

HTML code is quite simple, the idea is to display the native HTML checkbox plus the images, CSS will do the rest. We create a label that is the parent of the checkbox and the images:

<label class="container">
    <input type="checkbox">
    <img class="img-unchecked"  src="https://lucidar.me/en/web-dev/files/unchecked.png" width="16px">
    <img class="img-checked"    src="https://lucidar.me/en/web-dev/files/checked.png"   width="16px">
    Text of the checkbox
</label>

Note that the images have a class attribute (img-unchecked and img-checked). These attribute will be used to hide/show the images according to the checkbox status.

CSS

Container

You problably noticed the carret appears when the user click in the text of the checkbox. To prevent this, let's add caret-color: transparent; to the main container. You can also change the mouse cursor with cursor: pointer;. To keep the same behavior as native HTML checkboxes, we also add display: block; to prevent checkboxes being on the same line:

.container {
    cursor: pointer;
    caret-color: transparent;
    display: block;
}

Hide the HTML checkbox

Let's start by hidding the native HTML checkbox :

/* Hide the browser's default checkbox */
.container input {
  display: none;
}

The checkbox will not be displayed.

Hiding the checked images

Now let's hide the image for the checked checkbox :

/* Hide the checked checkbox */
.img-checked {
    display: none;
}

We hide the checked image because the default value of the checkbox is unchecked.

Switch images

Here is the behavior of the CSS for switching the image.

/* If checked, show the checked image */
.container input:checked ~ .img-checked {
    display: inline;
}

/* If checked, hide the unchecked image */
.container input:checked ~ .img-unchecked {
    display: none;
}

It's as simple as that:

Improvements

One can also add a third images that appears when the mouse is over the checkbox. To do so, add a third image in the HTML and adapt the following CSS to you needs:

.container:hover input:not(:checked) ~ .img-hover {
    display: inline;
}

.container:hover input:not(:checked) ~ .img-checked {
    display: none;
}

.container:hover input:not(:checked) ~ .img-unchecked {
    display: none;
}

Here is the result:

See also


Last update : 10/02/2022