Radio buttons are awesome, but there’s not much you can do to style them.
Say you have a form that lets users pick a category of food and then answer questions about that food. You might have fruit, bread, meat, etc. as categories.
Wouldn’t it be great to have the radio buttons be images of food and let them click on the image they’re interested in?
Sadly, you can’t. You can’t turn off the default styling of radio buttons, give them background images, etc.
But with a little jQuery and CSS trickery, you can fake it! See the demo here.
HTML
<form name="testform" method="post" action="options.php">
<h2>Choose a category</h2>
<p>
<input type="radio" value="1" name="category" id="category_1" class="hidden" />
<a id="category_fruit" href="javascript:set_radio('category_1');" class="radio-picture"> </a>
<input type="radio" value="2" name="category" id="category_2" class="hidden" />
<a id="category_vegetables" href="javascript:set_radio('category_2');" class="radio-picture"> </a>
<input type="radio" value="3" name="category" id="category_3" class="hidden" />
<a id="category_meat" href="javascript:set_radio('category_3');" class="radio-picture"> </a>
<input type="radio" value="4" name="category" id="category_4" class="hidden" />
<a id="category_bread" href="javascript:set_radio('category_4');" class="radio-picture"> </a>
<input type="radio" value="5" name="category" id="category_5" class="hidden" />
<a id="category_dessert" href="javascript:set_radio('category_5');" class="radio-picture"> </a>
</p>
<div id="questions-wrap">
</div>
<input type="submit" value="Continue" id="food_submit" name="food_submit" />
</form>
Each radio button has the class “hidden” and is paired with an <a> tag with the class “radio-picture“. Clicking on an <a> tag triggers a JavaScript function named “set_radio()” that is passed the ID of its paired radio button.
CSS
a.radio-picture {
border: 1px solid black;
display: inline-block;
height: 50px;
margin-right: 10px;
text-decoration: none;
width: 50px;
}
a#category_fruit {
background: url("images/category/fruit.png") no-repeat scroll 0 0 white;
}
a#category_vegetables {
background: url("images/category/veggies.png") no-repeat scroll 0 0 white;
}
a#category_meat {
background: url("images/category/meat.png") no-repeat scroll 0 0 white;
}
a#category_bread {
background: url("images/category/bread.png") no-repeat scroll 0 0 white;
}
a#category_dessert {
background: url("images/category/dessert.png") no-repeat scroll 0 0 white;
}
.hidden {
left: -10000px;
position: absolute;
top: -1000px;
}
The “radio-picture” class sets the basic parameters of the image buttons. Then each individual button gets an appropriate picture. The “hidden” class moves the input buttons out of the browser viewport. This makes them invisible but still functional. If we simply set them to “display:none;”, they would no longer work.
JavaScript
function set_radio($inputid) {
$("input#" + $inputid).click();
}
The jQuery is dead simple. It takes the radio button ID passed to it and clicks that button.
Summary
Put it all together and you get the following:
- A series of category images that are links.
- Clicking on an image triggers a JavaScript function that clicks the associated — but invisible — radio button.
To finish the example, you would have another jQuery function that would display additional questions based on the category chosen. It would look something like this:
$(document).ready(function() {
$("input:radio[name=category]").click(function(){
var $id = $(this).val();
$.post("determine_next_questions.php", {prodfamily:$id}, function(data){
$("#questions-wrap").html(data);
});
});
});







Can you post a demo? Would be really helpful!
Yes! I’ve finally set up a demo section. I’ve updated the post to add a link to the demo, or you can just click here.
I’m confused why this couldn’t all be done with only css?
As discussed in the post, it’s because you can’t apply background images or other necessary styles to radio buttons. If you have a CSS-only method, please share!