Pretty checkboxes with jQuery
I’ve rewritten some of this so it is valid for XHTML 1.0 Transitional. I also fixed a bug whereby the “pretty” version of the form did not recognize preselected checkboxes.
The core method I show below would also work great for radio buttons. Bagwan Pankaj, Sean Foushee and Philip Beel all have since offered great tutorials on how to extended this concept to radio buttons.
I was working on a project recently where form checkboxes were required, but the standard UI would not do. I needed something a little more engaging. So in this short tut, I’ll show how to turn this…

…into this

Using some CSS and jQuery. You can see this simple demo here. Those new to jQuery should check out these tutorials and resources.
I’m sure you’re psyched. Let’s get started…
1. Form markup
So normally you’d have some structure like this:
All well and good, but we need more. We will use list items to hold the checkboxes, content and controls:
The checkboxes are still there, but we won’t be clicking them. The checking/unchecking will handled by the “Select” and “Cancel” links within each list item.
2. Backgrounds
Each list item has a selected (green) and deselected (grey) state. This is most easily taken care of by using one background image, and shifting the position when needed. Fire up Photoshop and create these images:

The list items will be 105 pixels wide and 150 pixels tall, so checkboxbg.gif should be 210 pixels wide (double the width). When it is selected, the background will shift to the left by 105 pixels to expose the green side. We’ll get to the CSS for this shortly.
Sendit.gif and select.gif will serve as backgrounds for the submit button and select link, respectively.
3. CSS
legend {
font-size: 17px;
}
fieldset {
border: 0;
}
.checklist {
list-style: none;
margin: 0;
padding: 0;
}
.checklist li {
float: left;
margin-right: 10px;
background: url(i/checkboxbg.gif) no-repeat 0 0;
width: 105px;
height: 150px;
position: relative;
font: normal 11px/1.3 "Lucida Grande","Lucida","Arial",Sans-serif;
}
.checklist li.selected {
background-position: -105px 0;
}
.checklist li.selected .checkbox-select {
display: none;
}
.checkbox-select {
display: block;
float: left;
position: absolute;
top: 118px;
left: 10px;
width: 85px;
height: 23px;
background: url(i/select.gif) no-repeat 0 0;
text-indent: -9999px;
}
.checklist li input {
display: none;
}
a.checkbox-deselect {
display: none;
color: white;
font-weight: bold;
text-decoration: none;
position: absolute;
top: 120px;
right: 10px;
}
.checklist li.selected a.checkbox-deselect {
display: block;
}
.checklist li label {
display: block;
text-align: center;
padding: 8px;
}
.sendit {
display: block;
float: left;
top: 118px;
left: 10px;
width: 115px;
height: 34px;
border: 0;
cursor: pointer;
background: url(i/sendit.gif) no-repeat 0 0;
text-indent: -9999px;
margin: 20px 0;
}
As I mentioned above, the effect of adding a class of “selected” to the list item shifts the background image, hides the “Select” link and shows the “Cancel” link. The checkbox itself is also hidden entirely (but it needs to be present in the markup).
4. jQuery
Here’s where we weave this together.
$(document).ready(function() {
/* see if anything is previously checked and reflect that in the view*/
$(".checklist input:checked").parent().addClass("selected");
/* handle the user selections */
$(".checklist .checkbox-select").click(
function(event) {
event.preventDefault();
$(this).parent().addClass("selected");
$(this).parent().find(":checkbox").attr("checked","checked");
}
);
$(".checklist .checkbox-deselect").click(
function(event) {
event.preventDefault();
$(this).parent().removeClass("selected");
$(this).parent().find(":checkbox").removeAttr("checked");
}
);
});
});
Line 4
Looks to see if there are any pre-checked checkboxes, and assigns the appropriate class if there are any.
Line 7
This selector grabs all those green “Select” buttons and assigns a script to the click event.
Lines 9, 10, 11
We want to prevent the link from invoking its default behavior of reloading the page, and continue with our instructions. The $(this) object refers to the “Select” button itself:
Select
So $(this).parent() refers its parent in the DOM, which is the <li> element. This is the element we want to add a class of “selected” to. Finally, line 11 makes sure that the checkbox is actually selected by setting its “checked” attribute.
Line 16
This selector catches all the “Cancel” links (which become visible when the list item’s class is set to “selected”).
Lines 18, 19, 20
This essentially undoes everything we did in lines 9, 10 and 11 above.
So what can you do with this?
Anything you want. You can keep things simple and familiar by creating custom designed checkboxes, or take a more innovative approach and employ a more creative multiple selection UI. You could even create a toggle switch like those found in the iPhone settings. This tutorial is more of a starting point. As I mentioned above, there are some other tutorials you can check out based on this concept applied to radio buttons.
Nice post. Can you follow it up with a post on how to handle validation using this technique?
Great tutorial, thanks Aaron.
Don’t forget to include “outline: 0;” in the CSS for your links, however. As it is now, you get a funky dotted outline in Mozzila browsers that spans the left side of the window whenever you click on one of the items.
working on a prototype framework version of it.
Done deal! thanks for the code Aaron!
document.observe(‘dom:loaded’, function(){
$$(‘.checkbox-select’).each(function (event) {
return $(event).observe(‘click’, function(event) {
$(Event.element(event)).up().addClassName(‘selected’);
$(Event.element(event)).previous(1).writeAttribute(‘checked’, ‘checked;’);
});
});
$$(‘.checkbox-deselect’).each(function (event) {
return $(event).observe(‘click’, function(event) {
$(Event.element(event)).up().removeClassName(‘selected’);
$(Event.element(event)).previous(2).removeAttribute(‘checked’);
});
});
});
Well cone, Caio – hope you find some application for it!
[...] Go to Source [...]
I like it very much the customization of the checkboxes. I’m elaborating an article at my site with a list of checkboxes or form elements fancy customization. Thanks. I will surely give you credit back.
[...] Aaron WeyenbergMuy creativo y diferente a lo que comúnmente han visto, miren la demo para que vean de lo que estoy hablando. [...]
Just a little cross-browser fix. Internet Explorer didn’t like native “removeAttribute” much so use prototype’s writeAttribute(’checked’, false) instead:
document.observe(’dom:loaded’, function(){
$$(’.checkbox-select’).each(function (event) {
return $(event).observe(’click’, function(event) {
$(Event.element(event)).up().addClassName(’selected’);
$(Event.element(event)).previous(1).writeAttribute(’checked’, true);
});
});
$$(’.checkbox-deselect’).each(function (event) {
return $(event).observe(’click’, function(event) {
$(Event.element(event)).up().removeClassName(’selected’);
$(Event.element(event)).previous(2).writeAttribute(’checked’, false);
});
});
});
Thanks Caio, good catch!
Awesome… but totally not xHTML valid… even transitional
Would be perfect to have it valid with W3C. can’t be that hard !
Very impressive work. Pretty much screams out for a plugin, eh?
An easy way to make it valid would be to remove the label tag and change each paragraph inside the form to a label for each option (brings much better accessibility for non-visual UAs too).
Would be nice if the cancel select button covered the whole of the button area, including the check mark, but that’s an easy CSS fix.
[...] Pretty checkboxes with jQuery [...]
Pretty checkboxes with jQuery…
Making pretty checkboxes with jQuery and CSS….
[...] Pretty checkboxes with jQuery | Aaron Weyenbergaaronweyenberg.com [...]
[...] Pretty checkboxes with jQuery. (uses images). Link. [...]
[...] Pretty Checkboxes with jQuery Aaron is a New England based web designer, he was working with a project where form checkboxes were required, but the standard UI would not do. So below is something he came up with. [...]
cool one … will be very help full….. thnx for sharing !
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery [...]
[...] Pretty Checkboxes with jQuery [...]
Is there any way to use radio buttons instead of checkboxes?
Great tutorial by the way!
Thanks for the responses. Yes it’s true, it is not xhtml valid. I’m planning to update it to remedy that. At the time I created it, my goal was to just get it done.
@Zilus – I’m sure this could be done without much trouble. Perhaps I will write a variation of this for radio buttons as well.
[...] Cases à cocher avec jQuery [...]
[...] Pretty checkboxes with jQuery [...]
[...] 31.使用jQuery的漂亮复选框 [...]
Would be nice to have the entire grey area clickable instead of the “Select” button. The UI problem with checkboxes is that user has to focus into the clickable area of the box itself, which even in this improvement is not much different as I now have to focus on the Select button. Perhaps you could use “label for” and make the entire thing clickable?
Also, will this work for both checkboxes and radiobuttons?
[...] Pretty checkboxes with jQuery [...]
[...] Caixas de seleção maneiras com jQuery [...]
[...] encuentro un completo tutorial con el que podremos reemplazar el aspecto de los elementos <input type=”checkbox” /> por otro [...]
[...] Link: Pretty checkboxes with jQuery Categorías:Diseño, jQuery Etiquetas:jQuery Comentarios (0) Trackbacks (0) Deja un comentario Trackbacks [...]
Really awesome method.
Short comment, ( more like a suggestion ) to process the checkboxes, make them into an array, like so: input name=”jqdemo[]”
Thanks Aaron!
Validation should be fairly simple really as despite the visuals it’s still a HTML input element, so you should be able to validate as you always would.
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery | Aaron Weyenberg (tags: tutorial jquery checkbox form) [...]
Nice! Try overflow:hidden in “a” css element to eliminate the dotted border around every link in FF…
Pretty cool!
[...] Pretty checkboxes with jQuery [...]
[...] Pretty checkboxes with jQuery | Aaron Weyenberg Checkboxes más bonitos con jQuery y CSS (tags: jquery javascript css howto tutorial) blog comments powered by Disqus var disqus_url = ‘http://dubo.cl/links-for-2009-08-28/ ‘; var disqus_container_id = ‘disqus_thread’; var facebookXdReceiverPath = ‘http://dubo.cl/wp-content/plugins/disqus-comment-system/xd_receiver.htm’; var DsqLocal = { ‘trackbacks’: [ ], ‘trackback_url’: ‘http://dubo.cl/links-for-2009-08-28/trackback/’ }; [...]
Awesome plugin… just need to find a project to use it… Thanks.
Have you done ant user testing with these elements?
They are pretty, but I suspect users will struggle with them.
Nice thats sounds good! I m sure that i can find a lot of situtation where i can use it…
I just had to stop by and say, good job on the custom checkboxes.
Great way to customize your forms. Users like familiarity so it is key to be careful with tampering with UI, but it sure looks good.
Very nice! I want to use this on my website. Everything works fine except for one thing.. if we add a checkbox already checked by default, it appears like it is not checked.
Wonderful work! As others mentioned it isn’t valid XHTML, but since I love the technique and want to use a modified version of this in a current project I rewrote the HTML, tweak some of the CSS and added one line of JavaScript, and voila! Valid XHTML, and a proper depreciated form:
http://combinedartsmedia.com/sean/select_boxes/select_smf.html
View the source to see the changes, I’ve added comments to show where I’ve updated the script and HTML. The CSS changes are fairly straight forward.
I’ve updated my page to include a write up and radio buttons!
http://combinedartsmedia.com/sean/check-boxes_and_radio-buttons/
(note, the old link in my post above will redirect to this one)
Great work! thanks for script