Helping you build a better website
(and other interesting web stuff)

CSSHTMLJavaScriptjQueryMSSQLMySQLPHPSilvaTechnologiesWordpress
Silva Web Designs - Blog

How to style Checkboxes and Radio Buttons using CSS

So you want to style checkboxes and radio buttons to look more awesome than the default styling? Well, you are in the right place. These input values are a bit of a pain, and the default options tend to look a lot different depending on which browser you are using. There are several ways to do this, but today we will show you a great solution that focuses on accessibility.

Let’s get cracking! In this tutorial we will be using the following:

  • ::before and ::after pseudo-elements
  • :checked CSS pseudo-class selector
  • + adjacent sibling selector

The great thing about using these techniques is that almost all browsers (IE 10 and above) have great support for this.

We are going to demonstrate how to do these using checkboxes, radio buttons use the same approach, just with slightly different styles; nail one, you got them both!

So firstly, let’s make your HTML markup like below:


<div class="checkbox">
    <input type="checkbox" id="my-checkbox">
    <label for="my-checkbox">CSS Only Checkbox</label>
</div>

What we have done here is wrap the input and label elements with a div called checkbox so that we know this part of code represents a checkbox.

For this to work in the way we will be demonstrating, the following things are required: (otherwise tweaks will be required based on your HTML markup)

  • The label must appear after the <input type="checkbox">
  • The id attribute is required on the <input type="checkbox">
  • The for attribute is required on the label

Now for the CSS, we are going to show this in steps, if you just want the full code; click here.

Step 1.

Since we can’t style the default checkbox using CSS, we are going to hide it. There are several ways to do this but we are going to hide it using opacity: 0 as follows:


.checkbox input[type="checkbox"] {
    opacity: 0;
}

Step 2.

Now we are going to create a ‘fake’ checkbox using pseudo-elements, this will be done by using the ::before and ::after pseudo elements.

We will use the ::before to create the outer box and ::after to create the checkmark.

Both of these elements will be positioned before the text in the label.

Let’s start by creating the outer box. What we will do here is make the ::before pseudo-element and inline-block and assign an equal width and height. We will add a border to make it visible. Depending on the way you wish to style it, this will look like this:


.checkbox label::before{
    content: ' ';
    display: inline-block;    
    height: 16px;
    width: 16px;
    border: 1px solid #000;   
}

Now, let’s create the checkmark using the ::after pseudo-element. We are going to set this as an inline-block element and assign it height and width. We’ll also add custom styles to its left and bottom borders and rotate it by 45 degrees to make it appear like a checkmark.


.checkbox label::after {
    content: ' ';
    display: inline-block;
    height: 6px;
    width: 9px;
    border-left: 2px solid;
    border-bottom: 2px solid;
    transform: rotate(-45deg);
}

In this next part, we will be aligning the outer box and checkmark. We will be using absolute positioning to position both pseudo-elements relative to the text in the label like so:


.checkbox label {
    position: relative;
}

.checkbox label::before,
.checkbox label::after {
    position: absolute;
}

.checkbox label::before {
    top: 3px;
}

.checkbox label::after {
    left: 4px;
    top: 7px;
}

Step 3.

Now, we are getting very close. We just need to create a way for the checkmark to appear/disappear based on the state of the checkbox.

You may have noticed that there is an ID for the <input type="checkbox"> and also for the attribute on the label. It’s possible to toggle the state of the default checkbox by clicking the label. The reason we placed the label after the <input type="checkbox"> is so that we can change the state using the adjacent (+) sibling selector as shown below:


/* Hide Checkmark */
.checkbox input[type="checkbox"] + label::after {
    content: none;
}

/* Show Checkmark on Checked State */
.checkbox input[type="checkbox"]:checked + label::after {
    content: "";
}

Step 4.

Now we have a working, custom styled checkbox. If you want to take this one step further and make it accessible, then keep reading!

We will use the :focus selector on the <input type="checkbox">, we can again use the adjacent (+) sibling selector to give the ::before pseudo-element (outer box) of the label a focus style. To do this, we can add the following code:


.checkbox input[type="checkbox"]:focus + label::before {
    outline: rgb(59, 153, 252) auto 5px;
}

And there we have it, folks, we now have a fully accessible, customisable and functional checkbox in just four simple steps.

Awesome right?

To Conclude

To create a custom checkbox using pure CSS your code will look as follows:

HTML


<div class="checkbox">
    <input type="checkbox" id="my-checkbox">
    <label for="my-checkbox">CSS Only Checkbox</label>
</div>

CSS


body {
    font-size: 20px;
    line-height: 24px;
}

.checkbox input[type="checkbox"] {
    opacity: 0;    
}

.checkbox label {
    position: relative;
    display: inline-block;
    padding-left: 30px;  
}

.checkbox label::before,
.checkbox label::after {
    position: absolute;
    content: ' ';
    display: inline-block;
}

.checkbox label::before {
    height: 16px;
    width: 16px;
    border: 1px solid #000;
    left: 0px;
    top: 3px;
}

.checkbox label::after {
    height: 5px;
    width: 9px;
    border-left: 2px solid;
    border-bottom: 2px solid;
    transform: rotate(-45deg);
    left: 4px;
    top: 7px;
}

.checkbox input[type="checkbox"] + label::after {
    content: none;
}

.checkbox input[type="checkbox"]:checked + label::after {
    content: ' ';
}

.checkbox input[type="checkbox"]:focus + label::before {
    outline: rgb(59, 153, 252) auto 5px;
}

You can view a demo of this here on CodePen.

We hope you loved this tutorial, if it has helped you or if you require any assistance with anything, feel free to drop us a comment below.

Nathan da Silva - Profile

Posted by: Nathan da Silva

Nathan is the Founder of Silva Web Designs. He is passionate about web development, website design and basically anything digital related. His main expertise is with WordPress, Magento, Shopify as well of many other frameworks. Whether you need responsive design, SEO, speed optimisation or anything else in the world of digital then get in touch. If you would like to work with Nathan, simply drop him an email at [email protected]

It’s good to share

Join the discussion