How to Create and Style an HTML Custom Checkbox

Katie Fedigan-Linton
4 min readSep 20, 2021

Ordering takeout. Creating a new profile. Making hotel reservations. These different online activities all have one thing in common: the checkbox.

The checkbox is a basic yet versatile tool used across a variety of industries. It allows users to customize their online experience and allows marketers to collect vital audience metrics. However, despite the universal necessity of the checkbox, customizing them can be surprisingly tricky.

Developers using HTML to add borders, colors, and other custom styles to their checkboxes run into the same problem over and over again — none of their changes get applied. No matter what they try, the checkboxes remain in their default style.

To understand and solve this issue, let’s go over the HTML, why the checkbox is not so simple to customize, and the modern solution.


This part of the checkbox code is pretty straightforward. Create each checkbox with the <input> tag and identify each one with the <label> tag. For example:

<label class=”container”>A
<input type=”checkbox”>
<label class=”container”>B
<input type=”checkbox”>
<label class=“container”>C
<input type=”checkbox”>
<label class=”container”>D
<input type=”checkbox”>

The resulting checkboxes look like this:

While this technically accomplishes the goal of making checkboxes, it looks pretty boring. Adding some <br> tags and other basic HTML formatting will help, but will never be enough to make dynamic checkboxes that align with the overall look and feel of your website.

But why? Why is something as fundamental as customizing checkboxes beyond the reach of HTML?

The short answer: browser defaults.

The Problem

When a browser reads your HTML, it uses its internal stylesheet and default settings to translate the code into a fully functional website. This ensures that your headings are larger than the body text, that links are highlighted, paragraphs are spaced out — all the things users need for your website to be both legible and engaging.

However, these default settings vary based on which browser you’re using. Safari and Chrome have different default font families, for example, which means the font on your site may change depending on which browser your audience is using.

No matter what custom style you may try to incorporate into your HTML, browsers will ignore it in favor of their own default settings. Talk about a UI nightmare!

To overcome this problem when making a customized checkbox, developers used to use clunky hacks like creating images and icons for each checkmark, or coding in JavaScript. This required a lot of extra work and rarely resulted in elegant checkboxes that matched the overall look and feel of the website.

Today we have a better way: CSS.

The Modern Solution

CSS (Cascading Style Sheets) is a coding language that specifies how HTML is presented on your website. It can be used for basic text styling, like changing the color or size of headings, or it can be used for more complex tasks like creating your website layout with a main content area and a sidebar for related information. It can even be used to make animation.

CSS is an extremely versatile tool and, in this case, it will enable us to create elegant, fully customized checkboxes.

First we need to go back to the HTML and add the <span> tag to each checkbox. This change will allow us to customize the HTML using CSS. For example:

<label class=”container”>A
<input type=”checkbox”>
<span class=”checkmark”></span>

Next, we need to write the CSS code to format the HTML. For example:

/* Customize the label (the container) */
.container {
display: block;
position: relative;
padding-left: 25px;
margin-bottom: 10px;
cursor: pointer;
font-size: 22px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Create a custom checkbox */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 15px;
width: 15px;
background-color: #eee;
/* On mouse-over, add a grey background color */
.container:hover input ~ .checkmark {
background-color: #bbb;
/* When the checkbox is checked, add a green background */
.container input:checked ~ .checkmark {
background-color: #26f321;
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: “”;
position: absolute;
display: none;
/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
display: block;
/* Style the checkmark/indicator */
.container .checkmark:after {
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);

There’s one final piece of code we need to add to the CSS in order to ensure that the browser ignores its own defaults in favor of the code we’ve written:

/* Hide the browser’s default checkbox */
.container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;

The results will look like this, regardless of browser defaults:

Ready to Code?

Whether you’re making a site for hotel reservations or you simply want users to opt in to your mailing list, checkboxes are an essential tool for developers. Use the above code to create dynamic checkboxes that are in line with the overall look and feel of any website, regardless of which browser your users choose. With CSS, we can now achieve elegant solutions to problems outside the scope of HTML.



Katie Fedigan-Linton

Freelance writer for hire. Politics, current events, cybersecurity, fiction, TV, film, etc. Tip jar: