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:
To this:
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:
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:
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.
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.
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.
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.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
- CSS-Tricks: Stuff you can do with the Checkbox Hack
- Completely CSS: Custom checkboxes, radio buttons and select boxes
- Envato Tuts+: Quick Tip: Easy CSS3 Checkboxes and Radio Buttons
- Stack Overflow: How to style checkbox using CSS?
- CSS Checkbox Styles
- Creating Custom Form Checkboxes and Radio Buttons with Just CSS!
The Conversation