Customizing Radio Buttons and Checkboxes

Last Updated December 6, 2016

Pinterest image for Customizing Radio Buttons and Checkboxes

As a designer, one of my favorite touches is to customize the design of a radio button and checkbox. In my humble opinion, it’s just one more step toward finesse that says, “I’ve taken the extra step to make sure that my site, in its entirety, is branded and cohesive.”

Compare this:

Form Fields - Boring

To this:

Form Fields - beautiful

See what I mean?

So, how do you go about implementing a custom design? and is there a way to do it within CSS, so that you retain your HTML mark-up and the browser’s default behavior?

Yes!

What we’re trying to achieve

Here’s our image mock-up:

Form Fields - Mock Up

The HTML

Let’s go ahead and write our HTML:

<label>What's your favorite part of the process?</label><br />

<input type="radio" name="process" value="discovery" id="discovery" checked />
<label class="choice" for="discovery">Discovery</label><br />

<input type="radio" name="process" value="design" id="design" /><label class="choice" for="design"> Design</label><br />

<input type="radio" name="process" value="development" id="development" /><label class="choice" for="development"> Development</label><br />

<input type="radio" name="process" value="quality assurance" id="quality_assurance" /><label class="choice" for="quality_assurance">Quality Assurance</label><br />

<input type="radio" name="process" value="launch" id="launch" /><label class="choice" for="launch">Launch</label><br />

<input type="radio" name="process" value="maintenance" id="maintenance" /><label class="choice" for="maintenance"> Maintenance</label>

<hr />

<label>What languages do you know?</label><br />

<input type="checkbox" name="languages" value="html" id="html" checked /> 
<label class="choice" for="html">HTML</label><br />

<input type="checkbox" name="languages" value="css" id="css" /> 
<label class="choice" for="css">CSS</label><br />

<input type="checkbox" name="languages" value="sass" id="sass" /> 
<label class="choice" for="sass">Sass</label><br />
 
<input type="checkbox" name="languages" value="javascript" id="javascript" /> 
<label class="choice" for="javascript">JavaScript</label><br />
 
<input type="checkbox" name="languages" value="php" id="php" />
<label class="choice" for="php">PHP</label><br />
 
<input type="checkbox" name="languages" value="mysql" id="mysql" /> 
<label class="choice" for="mysql">MySQL</label>

This is what our code looks like rendered out:

Form Fields - Plain Code

First, let’s talk about why we structured our radio buttons and checkboxes the way we did. It followed this formula:

<input id="input_id" /> <label for="input_id">option</label>

The id attribute on the input, allows us to connect it to the appropriate label using the for attribute. You’ll notice the 2 values match.

Why is this important? Well, one, it’s semantic, but two, the user can actually click on the label, and the radio button / checkbox will be selected. It increases our target area. Plus, as we dig in to the styling, it allows our code to continue to operate as expected.

Animated Label / Checkbox

The CSS

The Radio Button

Let’s start with the radio button. There’s not a lot we can do stylistically, out of the box.

Just try adjusting the width and height.

input[type=radio] {
	height: 50px;
	width: 50px;
}

It doesn’t change the size of the radio button, it just modifies the space around the button.

Radio Button - 50 x 50

Not exactly, what we were hoping for.

NOTE:

Did you know we could do this, within CSS, input[type=radio]?

The [] brackets signify an attribute within our HTML.

For future reference, you can use this convention to reference other things, like div[data-value=something] would apply to <div data-value="something"></div>.

Let’s try changing the radio button’s background color:

input[type=radio] {
	background: red; 
}

Nothing. Ugh.

Plain Code - Radio Buttons / Checkboxes

It looks like we’ll need hide the radio button altogether:

input[type=radio] {
	display: none;
}

But, now what?

Well, we can use the radio button image and apply it to the background of our label tag.

label {
	background: url('https://lh3.googleusercontent.com/CSygHWUdWSpIIfoPv3gwc0PctzOTVFGSCcSel4lOtxBBofmpt1QJxOF8MwrXbi0lIxxnKw2Cj6btMFTJZIGxWpkNpHZL41cOa5sgeSgtlsmat7YjkQlrU2XbmhPrxZwElMf9hucSAfEgF0VRLQy58ATRdf1mQULv5VcfnWFyus03KF8Egtg_pwW1_LRnklFEAUUZ_TyzEqFM3cp6G_aDyQpNCKxNvoLWkrcV-tgxqxQGAqC45JAkWWNXSxKgXD8TINX_xO1oml6fh_qVC32SwSQZqkk8Mkhvi2V3DSME0BzcS7wlku5tUK9ijkksro3Wp9kS7Ng4kyPDpkhZAh0kaiKXe4vUXfpZhhXuVjMwaP04HmMFJ7tjKt7bKvIHo0LcKv1zbbQsJ5ZTbI9wRabnUk9dWZtKE0w9BwiNbHuw1JrJBzmSCon9aQZD2DCD72DZEgaUchpdWKi-jShqHvrhaUYUeOUQiImDmo9NBKocQIW76p69uns8tbm1XXohE6tc-PKj8Cx66YtZLm4oUsvppee7Sw92GBFNvMPP9BGZSvxZmpV6TV5rNga1JBJOCMKw76SuYRNob9jCPmjzVMYjmFN8GknmaqOti7kh-QP7IlTUleyq=w25-h24-no') left top no-repeat;
	display: block;
	min-height: 25px;
	padding-left: 35px;
}

NOTE:

Sorry about the crazy image URL. You can thank Google Photos.

Radio Buttons - Style Step 1

It looks right, but it doesn’t function like a radio button. Plus, it got applied to all label tags.

This is where a little bit of CSS Wizardry comes in to play.

You can actually target an element, if and only if two specific elements are right next to each other:

input[type=radio] + label {
	...
}

That + does the magic. It says, when a radio button is right next to a label, style the label. Notice, it’s the second item, you’re styling, not the first.

Let’s modify our label selector:

input[type=radio] + label {
	...	
 }

Now, to handle the checked state, let’s add another class that uses pseudo elements to target checked radio buttons:

input[type=radio]:checked + label {
	background: url('https://lh3.googleusercontent.com/QSVgoBuOonsWKUZm6m0NKwekEvkfMOWrPFfevisISZjzeu2uQkxMOY1MUh3QgorRu2qc1kwKX4So7-mGJ-hayMAitq15L63KQNBfsOcm1qmWDU657CNl4lauYhgVz7f59IMrZBg8FWdgh26VDCvGMwUqaK6CBVv13AdKbxDMeDqiZS73EgzF5kBW5smh1nxCY5Gqk8yCmDsYh4KixdZWKGW7BqXLZn7cB2fQV4-o0DePjN69GJLXmddJ6H32CBgiFKE4smBvb1ByWpREmRYpFEUaHuQdbhHiiebI4Kipz35I6OxsVxKC6HOIQC3Xk6JVePhgudB2_-8Nyq2M9rWqIap8kAhmN-FI8iRdSLXhTV4FEeTHqokQ0qEXEZ5N9dRKoXT3al1Alcwrson_OtaALHldR9O7BO6Iq5_BV7-ERpoSYD8wGGhCcWQbjKkz5qHTa8yWRAfZaCLnK8Dzs0DPJtgMjQirittz8cpQQxQM4fhzXvG2x_Dtev4Y1YcZbzsaU6FpamC188SkjEDGOjYnf6CTk0VVbPk1DXFPIEGbOmc7b1unsq7uHOOkuRkGnTQ_d8aLNNPpeDvxP4agpI-ycfdH2ciG4sRXSKcdeAXGIHhNaI9T=w25-h24-no') left top no-repeat;
}

Now, everything works like you would expect a radio button to work, because the label handles the clicking. (Remember, we talked about that earlier, in this post?)

The Checkbox

Most of our code will transfer over to the checkbox. The biggest difference is instead of using input[type=radio], we’ll be using input[type=checkbox] with different background images:

input[type=checkbox] {
	display: none;
}
 
input[type=checkbox] + label {
	 background: url('https://lh3.googleusercontent.com/Xxv2PonyC_el80dSzxdDFkgF7gM_Ru7u9ErRZS9hJeC9V1W073WowYQIhyivqHd74mt7GQBpL8aK9Aqsv9Kf2Ku_hjmsXsAZstjM0jFW4iQ85BYM41OnftEitTSzC0VagQ0hAxAYBbvTlOztGsDf5WOTW39gixPLf7DTZ72-YKANYzf1nMSH6Pc2b4_MTf4deEku7cS_xenmFAwlO5wM9lAs2TXRbOJBmuJmlIm1f6Zv7CNQR96yldK98z9QtDkDiZib2YxdFNXK_eLec8yWy-syA3imgmBDrlCR7BGZzVN36PTJDe5yChArZ-Gn2QHZAwsMCtKys_tKjngmgnYvTyj182U3jTz1Lt0N9OLpv_N4ouK8o4QEvvGs8BOTx9jAnlHoDY8D_QsKLgf_Vo1OG_DCJj67b3MTu9BYU4o3UXQgjTx7R-fHrl8V_zSHpaJyN61dwt0wVX9kerZxfxdFLnKu2CQOBITobLfZK0Q9T4REe2goZOqX0EQHfvLWuLlw7cur_VdXJctEKYCqINzeYxFqeyh1VGRkOjaY-ke73m8KkG2EYSlym7p1sYnX53xzNG66C5vCvHRm7624WZj9a2pTXSwjLCGEcQYtZ96nPTUYmrn-=s23-no') left top no-repeat;
	padding-left: 50px;
}
 
input[type=checkbox]:checked + label {
	background: url('https://lh3.googleusercontent.com/HtfShMuTVS5ellcvc4pNootlL8UKbR93Q6XHDDhcXmlxB6ImLN_A5WpYZSGDT_NJjPIK7MUl2jlwdFnD6RNYKak6bEYJ0X453PgqaNS_TEWp8Ck4fysY6Rx08jfENtWmpPETSqOeB3BoSLVuD8ZUdXlJ37ArYTmDbsCQA41zTuD1lT2m59ze9odMF2PB8FEQimdJtkyq1572ywgIdZwlimHTn3fgLK2OHza42kl22Wr4_JX1Ih1yEaqjQQTYS-5uGyiZat0SqRNoxdoYilsqcgQ0fLGiKjaPQb7gGbVjl1NFzfP5Mbyu7sOIQQ8sbRAZx63rNbD-fhvG5bLFuYulqyO6VBTBJ82KtumHkUV1ejR0sRn6hK-eFWJ7jvl1wnoqM3Ps6yFh7Jsl67r_9Yr5WF-nTwGYX979k0R7ZGmeL82tg2PGdzUlfiez6iuE6jByvEMsLC3QCLbUhA8-IY9pX-bi3b1YHq4jPk1Up5o1m15i1QuQk0fE4QuRNPBrd8L54bSjFF7mqmAdDwvC5y8wuj8O3GPYF5KA9AupDJIsE5C5-DcbkIhjvcBDaLHSpDq8KLI5BRUE9PunQl9GUrW3BdFagrJ1l79MmysIwewy_yGHRbnI=s23-no') left top no-repeat;
	display: block;
	min-height: 23px;
	padding-left: 50px;
}

See, that was easy?


Altogether, now

Here’s our final display:

See the Pen Self Teach . me // Customizing Radio Buttons and Checkboxes by Amy Dutton (@ahaywood) on CodePen.


Resources


The Conversation