Advertisement
  1. Web Design
  2. UX/UI
  3. Forms

Quick Tip: Easy CSS3 Checkboxes and Radio Buttons

Scroll to top

Ever wondered how to style checkboxes and radio buttons, but without JavaScript? Thanks to CSS3 you can! Here’s what we’re going to build (note: to learn how to make these accessible, check out this tutorial too):

If you’re looking for some graphics to use with your form UI elements, take a look at the UI kits available from Envato Elements. Otherwise, grab a cup of coffee and get started with this tutorial!

1. Understanding the Process

Recommended Reading: The 30 CSS Selectors you Must Memorize

For those of you that feel confident in your CSS abilities already and just want a nudge in the right direction, here is the most important line of CSS in the entire tutorial:

1
input[type="checkbox"]:checked + label {
2
3
}

Now, for those of you who feel you may need more direction, fear not,read onward!

Alright, so back on topic now. What exactly will we be doing? Well, due to CSS3’s nifty little :checked pseudo selector, we're able to target an element based on its checked (or unchecked) status. We can then use the + adjacent sibling selector from CSS2.1 to target the element directly following the checkbox or radio, which in our case is the label.

2. Setting up our HTML

Now, we start off by creating our HTML and CSS files (or however you prefer handling your styles) and get to work. I'll assume you know how to do that, so we won't have to get into it.

For the purpose of getting you on your way, I will only demonstrate this technique on a checkbox, but the process for radio buttons is identical, and is included in the source.

Okay, let’s actually begin then, shall we? We start by creating our checkbox input, followed by a label.

1
<input type="checkbox" />
2
<label>Styled Check Box</label>

Now, just in case you don't know much about the <label> element, you must connect the input and the label in order for you to interact with the input through the label. This is done by using, for="" and the input’s ID.

1
<input type="checkbox" id="c1" name="cc" />
2
<label for="c1">Check Box 1</label>

I also will add a <span> inside of the label, which is more personal preference than anything else, but all will become clear in step 3.

3. What We’re Here For: CSS

This is where the fun begins. First thing we do, which is the basis for this whole tutorial, is hide the actual checkbox.

1
input[type="checkbox"] {
2
    display:none;
3
}

Now that that’s done, we can style the label, but more specifically the span inside of the label. I do it this way in order to give myself more control over the exact position of the check box. Without it you would probably be using a background image in the label directly, and positioning it may become difficult.

1
input[type="checkbox"] {
2
    display:none;
3
}
4
input[type="checkbox"] + label span {
5
    display:inline-block;
6
    width:19px;
7
    height:19px;
8
    background:url(check_radio_sheet.png) left top no-repeat;
9
}

Alright, let me explain this quickly. First off, notice the background. I have a small sprite sheet for these, so all I have to do is set the background position on this span. The span itself is the exact width and height of each "sprite" in the sheet, making it easy to define each state.

Our sprite sheetOur sprite sheetOur sprite sheet
Our sprite sheet

Here is the rest of the CSS, specific to my styling. This is purely for aesthetics and specific to either my taste or this design.

1
input[type="checkbox"] {
2
    display:none;
3
}
4
input[type="checkbox"] + label span {
5
    display:inline-block;
6
    width:19px;
7
    height:19px;
8
    margin:-2px 10px 0 0;
9
    vertical-align:middle;
10
    background:url(check_radio_sheet.png) left top no-repeat;
11
    cursor:pointer;
12
}

4. Making it Work

There’s not too much work left, so let's get this wrapped up. The last thing you will need to do is provide a state for the element when the input is checked, and optionally also for on hover. This is quite simple, just take a look!

1
input[type="checkbox"] {
2
    display:none;
3
}
4
input[type="checkbox"] + label span {
5
    display:inline-block;
6
    width:19px;
7
    height:19px;
8
    margin:-2px 10px 0 0;
9
    vertical-align:middle;
10
    background:url(check_radio_sheet.png) left top no-repeat;
11
    cursor:pointer;
12
}
13
input[type="checkbox"]:checked + label span {
14
    background:url(check_radio_sheet.png) -19px top no-repeat;
15
}

Notice that because I used a sprite sheet, all I have to do is change the background position. Notice, also, that all I had to do to style the label’s span for when you “check” a checkbox/radio button, was use the CSS3 :checked pseudo selector.

Quick Note on Browser Support

Pseudo selectors have great support across all browsers, but the usual caveats apply, and the fallback is pretty graceful:

Can I use data for pseudo selectorsCan I use data for pseudo selectorsCan I use data for pseudo selectors
Can I Use data for general pseudo selectors
IE9 on Windows 7IE9 on Windows 7IE9 on Windows 7
Fallback: IE9 on Windows 7

Early mobile browsers are an issue too - support of :checked is unclear. Mobile Safari pre iOS 6 doesn't support it, for example.

Conclusion

Alright, so we’re done, right? Well let's just double check. First the HTML:

1
<input type="checkbox" id="c1" name="cc" />
2
<label for="c1"><span></span>Check Box 1</label>

Does yours look the same? Don’t forget to add in that <span>! When experimenting with this on your own, I highly suggest finding new or different ways of doing this part. I would love to see what you come up with to make it more efficient. Now for the CSS:

1
input[type="checkbox"] {
2
    display:none;
3
}
4
input[type="checkbox"] + label span {
5
    display:inline-block;
6
    width:19px;
7
    height:19px;
8
    margin:-2px 10px 0 0;
9
    vertical-align:middle;
10
    background:url(check_radio_sheet.png) left top no-repeat;
11
    cursor:pointer;
12
}
13
input[type="checkbox"]:checked + label span {
14
    background:url(check_radio_sheet.png) -19px top no-repeat;
15
}

Everything present? Perfect. Keep in mind that a lot of this styling is specific to the style I created for the demo files. I encourage you to create your own, and experiment with placement and presentation.

In conclusion, the most important thing you could carry away from this is the very first line of CSS I wrote at the very top:

1
input[type="checkbox"]:checked + label {
2
3
}

Using that, you can create a whole manner of different things. The possibilities with :checked go beyond checkboxes and radios for use in forms, but I’ll leave you to experiment with that on your own. Some things to experiment with:

  • Add a 2x spritesheet for retina screens
  • Use SVG instead of a bitmap

I hope you enjoyed this short article and I hope you take what you see here and expand or improve upon it!

Learn More About CSS Form Controls

Learn CSS: The Complete Guide

To finish off, we’ve built a complete guide to help you learn CSS, whether you’re just getting started with the basics or you want to explore more advanced CSS.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.